Skip to main content
Shopify Markets lets you sell to multiple regions from a single store with per-market product availability, currencies, and prices. Layers syncs your Markets configuration from Shopify and applies it to every storefront response — search results, collection browses, blocks, and facets — so each shopper sees the catalog and prices that match where they’re shopping from. This page covers what Layers syncs, how it picks the market for a given request, and the three application modes you can choose between.

What Layers Syncs

When Markets sync is enabled, Layers ingests four kinds of data from your Shopify Markets configuration:
DataDescription
MarketsEach active market, its handle, display name, primary_currency_code, and whether it’s the primary market.
RegionsThe country codes attached to each market. This is the lookup table Layers uses to resolve a shopper’s country into a market.
Per-Variant PricingThe 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 AvailabilityWhich markets each product is published to. Surfaces as the available_market_ids attribute on every product.
Sync is driven by 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 a context.geo.country field. Layers resolves that country into a market using the synced region table:
  1. The storefront pixel and the JavaScript SDK populate context.geo.country automatically from Cloudflare’s edge geolocation. Custom integrations should pass the shopper’s country explicitly (ISO 3166-1 alpha-2, e.g. "US", "GB", "JP").
  2. Layers looks up which market that country belongs to.
  3. The resolved market ID is attached to the request and used downstream for filtering, pricing, and meta.
If 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
{
  "context": {
    "geo": {
      "country": "DE",
      "province": "Berlin"
    },
    "shoppingChannel": "web"
  }
}

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 whose available_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.
ModeApplies Pricing?Filters by Availability?
offNoNo
pricing_onlyYesNo
strictYesYes

What Shows Up in API Responses

When a market is resolved for a request, Layers enriches the response in two places:

Variant Pricing

In strict 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:
{
  "_meta": {
    "pricing": {
      "currency_code": "EUR",
      "currency_decimal_places": 2
    }
  }
}
Use this on the storefront to format prices consistently — 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 where context.geo.country resolves to that market.

Per-Market Merchandising Rules

Once available_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

Pass context.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.