Skip to main content

Advanced Localization Guide

Use this guide after defining the canonical market table in Markets and Localization. The runtime invariant is simple:
Resolve one configured market at the request boundary, then use that same entry for routing, provider contexts, navigation, commerce, document metadata, and SEO.
Do not maintain a second locale list in routes, the Weaverse schema, a country selector, or sitemap code.

Request and Routing Contract

Match an Exact Allowlist

Supported market prefixes are configuration, not a pattern. Match the whole leading path segment, case-insensitively, against the configured pathPrefix values. At the request boundary:
  1. Serve a configured prefix such as /fr-ca with that market.
  2. Serve an unprefixed application path with the default market.
  3. Return 404 when the first segment has the exact locale shape xx-yy but is not configured, such as /en-xx or /zz-zz/products/hoodie.
  4. Keep ordinary content routes valid. /about-us, /hi-india, /collections/hi-in-picks, and /products/de-de are not leading xx-yy market prefixes.
An invented prefix that silently serves the default market creates an unbounded set of duplicate, non-canonical URLs.
The exact allowlist also handles React Router single-fetch paths. An invented market in /en-xx/products/hoodie.data must return 404 before the router handles the request.

Resolve Context Once

After selecting the market, create the Hydrogen Storefront context from that entry. Every Storefront API query then receives the active country and language through Shopify’s context instead of repeating variables in each loader. Use the public market identity for Weaverse localized content and Translation Manager. Shopify and Weaverse can require different language identities for the same market—for example, Shopify may require a script-specific enum while the public locale remains zh-tw. Store provider-specific values on the market entry and derive both contexts from it:
Hydrogen route loaders then call context.weaverse.loadPage({type, handle}) without parsing a locale again. An explicit locale argument remains useful for an intentional cross-locale admin or background operation; it should not replace the request-context contract for normal storefront loaders.

Preserve the Market Across Navigation

Build shared path helpers around the canonical table:
  • resolveLocale(path) returns only a configured market or the default for internal helper use.
  • delocalizePath(path) removes only an exact configured leading prefix.
  • localizePath(path, market) adds the target prefix and preserves the query.
  • localizedPathForRequest(request, path) localizes server destinations from the active request.
Do not use String.replace(prefix, ""). An unanchored replacement can corrupt a slug that merely contains locale-like text.

Locale Switches

A locale switch should preserve the current neutral path and query when the route is valid in the destination market:
Submit the market change as a document navigation—for example, React Router’s <Form reloadDocument>—rather than reusing the current route data. This ensures the next request rebuilds both the Shopify and Weaverse contexts and does not display stale localized content. If a resource handle is localized or unavailable in the destination market, redirect to a known valid destination instead of fabricating the same handle. Use the same helpers for application links and server redirects. In particular:
  • preserve the active prefix on login, account, cart, and post-action redirects;
  • preserve query strings and fragments on accepted same-origin paths;
  • keep React Router’s .data suffix and single-fetch redirect semantics intact;
  • validate public redirectTo form input as a same-origin absolute path before using it;
  • never build a redirect with string interpolation such as `${params.locale}/cart`.
A data request and its document request must resolve to the same market. Do not strip the prefix or .data protocol suffix in middleware.

Preserve Commerce Context

Market selection affects more than translated text:
  • update cart buyer identity with the selected country when switching markets;
  • localize cart action fallbacks and return paths;
  • set buyer identity before creating the checkout URL;
  • keep checkout continuity in the selected Shopify market and currency;
  • use localized Customer Account login, return, and logout destinations.
Register the storefront origin and every served origin/<prefix> home URI as an allowed Customer Account post-logout URI. The authentication callback itself remains unlocalized.

Render the Document Identity

Use the selected market’s public BCP-47 value and direction on the root document:
Use the public BCP-47 tag for Intl formatting as well. Do not build HTML language tags, URLs, or bundle keys from Shopify provider enums.

Emit Honest Canonical and Hreflang Metadata

Every indexable page should have a self-referential canonical URL for the active market. Emit hreflang only when the application knows that the equivalent route exists in every advertised market. A safe implementation uses an exact route allowlist. Pilot, for example, can prove equivalence for route families such as the home page, search, cart, product list, collection list, and policy list. It does not assume equivalence for:
  • product, article, page, or policy handles that Shopify may localize or unpublish;
  • Customer Account pages;
  • API, sitemap, or robots routes;
  • Weaverse custom pages published independently by market.
For an uncertain route, return no alternates. A fabricated alternate is worse than omitting hreflang. For a proven equivalent route:
  • generate one alternate from each configured market entry;
  • use its canonical hreflang value;
  • emit x-default for the default market;
  • keep sitemap alternates consistent with document metadata.

Resolve Theme and Merchant Translations

The Weaverse theme schema exposes bundled copy through i18n.staticContent and enables Translation Manager with translation: true. Keep merchant provenance separate from bundled fallback content. Resolve each migrated string in this order:
  1. live Studio design override
  2. persisted Translation Manager override
  3. genuine legacy merchant setting
  4. bundled/static market translation
Use own-property presence, not truthiness. "" can be an intentional live or persisted override and must not fall through. For a migrated key, keep one shared reader; passing the old setting as a second component prop creates conflicting precedence. A stored legacy value equal to the theme’s shipped default falls through to the market translation. Known limitation: the system cannot distinguish a merchant who deliberately selected that exact default from a merchant who never changed it.

Deployment Verification

For every configured market:
  1. Enable the intended country, language, and currency in Shopify Admin.
  2. Query the Storefront API with that context and verify the response reports the intended market and currency. Shopify may otherwise return the default without an error.
  3. Verify a representative document and .data request, localized link, redirect, cart update, and checkout transition.
  4. Verify <html lang> and dir, canonical URL, and only proven hreflang alternates.
  5. Verify unsupported exact locale-shaped prefixes return 404 and ordinary slugs still resolve.
  6. Verify all Customer Account post-logout URIs are registered.
  7. After deployment, sync and publish the intended theme keys and merchant overrides in Translation Manager.

Markets and Localization

Configure markets and manage localized content in Studio.

Rendering Pages

Load and render Weaverse page types from route loaders.

Custom Routing

Register application routes and custom pages.

Translation Feature Guide

Manage translatable theme keys in Weaverse.