What Layers Syncs
When Markets sync is enabled, Layers ingests four kinds of data from your Shopify Markets configuration:| Data | Description |
|---|---|
| Markets | Each active market, its handle, display name, primary_currency_code, and whether it’s the primary market. |
| Regions | The country codes attached to each market. This is the lookup table Layers uses to resolve a shopper’s country into a market. |
| Per-Variant Pricing | The price and compare_at_price Shopify exposes for each variant in each market’s currency. Stored in variant_market_pricing and joined into responses on demand. |
| Per-Product Availability | Which markets each product is published to. Surfaces as the available_market_ids attribute on every product. |
markets/create, markets/update, markets/delete, and product update webhooks — there’s no manual refresh required in normal operation. You can trigger a one-off refresh from the Catalog → Sync dashboard if you need to backfill historical data.
Markets sync is automatically disabled while the Global-E integration is active. Global-E manages its own localized pricing through a country rate table, so the two systems don’t run side-by-side. See Discount Entitlements for related Global-E details.
How Layers Picks the Market for a Request
Every Search, Browse, and Blocks request can carry acontext.geo.country field. Layers resolves that country into a market using the synced region table:
- The storefront pixel and the JavaScript SDK populate
context.geo.countryautomatically from Cloudflare’s edge geolocation. Custom integrations should pass the shopper’s country explicitly (ISO 3166-1 alpha-2, e.g."US","GB","JP"). - Layers looks up which market that country belongs to.
- The resolved market ID is attached to the request and used downstream for filtering, pricing, and meta.
context.geo.country is omitted, or if the country doesn’t map to any active market, Layers falls back to the primary market — the one marked is_primary in Shopify.
Example request context
Application Modes
Layers exposes three modes for how aggressively Markets data is applied to storefront responses. The mode is set on the Integrations → Shopify Markets page in the dashboard and defaults to Off for new stores.Off
Markets data is synced but not applied. Every shopper sees the full catalog and the variant’s default price, regardless of which market their country maps to. Use this mode when you’ve enabled Markets in Shopify but don’t yet want the catalog to localize — for example, while you’re auditing per-market product publishing before flipping the switch.Pricing Only
Layers applies the resolved market’s price and currency to every variant in the response, but does not filter products by market availability. Shoppers in any country see the entire catalog; they just see prices in the market’s currency. This mode is the right choice when:- You want localized prices everywhere but your catalog is fully published to every market.
- You’re rolling out market-aware pricing before publishing different products to different regions.
Strict
The full Markets experience. Layers applies the resolved market’s pricing and filters products to the ones published to that market. Products whoseavailable_market_ids array doesn’t include the resolved market are excluded from search, browse, and block results entirely.
This is what most multi-region stores end up running. Combine it with the available_market_ids facet attribute if you also want merchandisers to filter or segment by market inside Lab.
| Mode | Applies Pricing? | Filters by Availability? |
|---|---|---|
off | No | No |
pricing_only | Yes | No |
strict | Yes | Yes |
What Shows Up in API Responses
When a market is resolved for a request, Layers enriches the response in two places:Variant Pricing
Instrict and pricing_only modes, the price and compare_at_price on each variant (and the rolled-up price_range on the product) reflect the resolved market’s pricing, not the variant’s default Shopify price. The values are in the market’s currency, expressed in the same units Shopify exposes (a string like "19.99").
If a variant doesn’t have a row in variant_market_pricing for the resolved market — for example, the product was created before the market was published to — Layers falls back to the variant’s default price.
_meta.pricing
When market-aware pricing applies, the response includes a _meta.pricing object:
Intl.NumberFormat(locale, { style: "currency", currency: currency_code }) is the usual pattern.
The same
_meta.pricing shape is used by the Global-E integration when active. The shape of the object is stable across both integrations so your frontend doesn’t need to branch on which pricing provider is in play.available_market_ids on Products
Every product carries an available_market_ids array regardless of which mode you’re in (provided Markets sync is enabled). You can read it directly from any search, browse, or block result.
You can also expose available_market_ids as a filterable catalog attribute of type number to use it in merchandising rules, facets, and sort orders. See Filtering by Shopify Market for the setup steps.
Common Patterns
Localize Prices Without Localizing the Catalog
Set the mode to Pricing Only. Every shopper sees every product; the price they see is converted to their market’s currency.Region-Specific Soft Launches
Run in Strict mode. Publish a new product to a single market in Shopify, and that product will only appear in search and browse responses wherecontext.geo.country resolves to that market.
Per-Market Merchandising Rules
Onceavailable_market_ids is exposed as a catalog attribute, you can write merchandising rules whose conditions or actions reference it — for example, pin a hero product in the EU market but not in the US. Combine with contextual conditions on geo.country for finer geo targeting than market-level rules.
Auditing What a Shopper in Country X Sees
Passcontext.geo.country explicitly in a request from your own machine. The response will reflect whatever a real shopper in that country would see — same market, same pricing, same filtered catalog.
Limitations
- One market per request. Layers resolves exactly one market per request from
context.geo.country. There’s no notion of “multi-market” results in a single response. - Currency conversion is read from Shopify. Layers does not do its own FX. If Shopify hasn’t computed a price for a given variant in a given market, the fallback to the default variant price kicks in — even though that price is in the store’s primary currency.
- Strict mode can hide products from anonymous shoppers. Anonymous traffic from a country with no resolvable market lands on the primary market. Make sure your primary market’s product publishing covers the products you want anonymous visitors to see.
FAQ
Q: Can I use Shopify Markets alongside B2B catalogs?A: Yes. B2B catalog rules win for buyers signed in to a company location. Markets apply to everyone else. See B2B Catalogs for the precedence rules. Q: Do I need to call a different endpoint for each market?
A: No. Every storefront endpoint accepts
context.geo.country and resolves the market automatically.
Q: What happens if Shopify Markets is disabled mid-traffic? A: Layers continues serving cached data until the next webhook arrives, then disables sync. The application mode reverts to Off so shoppers immediately see the unfiltered catalog and default pricing. Q: How do I test a specific market locally?
A: Pass the country code explicitly in
context.geo.country — for example, "DE" to simulate Germany. Cloudflare won’t override the value if it’s already set.