docs/api-reference/store-api/localization.mdx
The Store API supports multi-language, multi-currency, and market-aware responses. Use request headers to control the locale, currency, and country for each request.
| Header | Example | Description |
|---|---|---|
X-Spree-Locale | fr | Language for translated content (product names, descriptions, etc.) |
X-Spree-Currency | EUR | Currency for prices and totals |
X-Spree-Country | FR | Country ISO code for market resolution |
Set locale, currency, and country once at initialization — all subsequent requests use these defaults:
import { createClient } from '@spree/sdk'
const client = createClient({
baseUrl: 'https://api.mystore.com',
publishableKey: 'pk_xxx',
locale: 'fr',
currency: 'EUR',
country: 'FR',
})
// All requests use fr/EUR/FR automatically
const products = await client.products.list()
Update defaults at any time:
client.setLocale('de')
client.setCurrency('EUR')
client.setCountry('DE')
Override client defaults for individual requests:
<CodeGroup>const products = await client.products.list({}, {
locale: 'fr',
currency: 'EUR',
country: 'FR',
})
curl -G 'http://localhost:3000/api/v3/store/products' \
-H 'X-Spree-Api-Key: pk_xxx' \
-H 'X-Spree-Locale: fr' \
-H 'X-Spree-Currency: EUR'
The X-Spree-Country header resolves the customer's market, which influences default locale and currency. Markets allow you to configure different pricing, languages, and product availability per region.
// Setting country automatically resolves the market
const products = await client.products.list({}, {
country: 'DE', // Resolves German market → EUR, de locale
})
curl -G 'http://localhost:3000/api/v3/store/products' \
-H 'X-Spree-Api-Key: pk_xxx' \
-H 'X-Spree-Country: DE'
When a market is resolved from the country:
X-Spree-Locale)X-Spree-Currency)You can also resolve the market explicitly using the Markets API:
<CodeGroup>// Resolve which market applies for a country
const market = await client.markets.resolve('DE')
// => { id: "mkt_xxx", name: "Europe", currency: "EUR", default_locale: "de", ... }
// Then set the client defaults
client.setLocale(market.default_locale)
client.setCurrency(market.currency)
client.setCountry('DE')
# Resolve market by country
curl 'http://localhost:3000/api/v3/store/markets/resolve?country=DE' \
-H 'X-Spree-Api-Key: pk_xxx'
Each value is resolved in the following order:
X-Spree-Locale headerlocale query parameterX-Spree-Currency headercurrency query parameterX-Spree-Country headercountry query parameterWhen a locale is set, all translatable fields are returned in the requested language. This includes product names, descriptions, category names, and other content managed through translations.
<CodeGroup>// English (default)
const enProduct = await client.products.get('spree-tote')
console.log(enProduct.name) // "Spree Tote"
// French
const frProduct = await client.products.get('spree-tote', {}, {
locale: 'fr',
})
console.log(frProduct.name) // "Sac Spree"
# English
curl 'http://localhost:3000/api/v3/store/products/spree-tote' \
-H 'X-Spree-Api-Key: pk_xxx' \
-H 'X-Spree-Locale: en'
# French
curl 'http://localhost:3000/api/v3/store/products/spree-tote' \
-H 'X-Spree-Api-Key: pk_xxx' \
-H 'X-Spree-Locale: fr'
If a translation doesn't exist for the requested locale, the API falls back to the store's default locale automatically.
All price fields in the response reflect the requested currency:
<CodeGroup>// USD prices
const usdProduct = await client.products.get('spree-tote', {}, {
currency: 'USD',
})
console.log(usdProduct.price) // { amount: "15.99", currency: "USD" }
// EUR prices
const eurProduct = await client.products.get('spree-tote', {}, {
currency: 'EUR',
})
console.log(eurProduct.price) // { amount: "14.49", currency: "EUR" }
# USD prices
curl 'http://localhost:3000/api/v3/store/products/spree-tote' \
-H 'X-Spree-Api-Key: pk_xxx' \
-H 'X-Spree-Currency: USD'
# EUR prices
curl 'http://localhost:3000/api/v3/store/products/spree-tote' \
-H 'X-Spree-Api-Key: pk_xxx' \
-H 'X-Spree-Currency: EUR'
Use the dedicated endpoints to discover which markets, countries, locales, and currencies are available. These are derived from your store's markets configuration.
List all markets to get the full picture of regions, currencies, and supported locales:
<CodeGroup>const { data: markets } = await client.markets.list()
// [
// { id: "mkt_xxx", name: "North America", currency: "USD", default_locale: "en",
// supported_locales: ["en", "es"], countries: [{ iso: "US", ... }, { iso: "CA", ... }] },
// { id: "mkt_yyy", name: "Europe", currency: "EUR", default_locale: "de",
// supported_locales: ["de", "en", "fr"], countries: [{ iso: "DE", ... }, { iso: "FR", ... }] },
// ]
curl 'http://localhost:3000/api/v3/store/markets' \
-H 'X-Spree-Api-Key: pk_xxx'
List all countries or countries within a specific market. Each country includes its market's currency and supported locales:
<CodeGroup>// All countries across all markets
const { data: countries } = await client.countries.list()
// Countries in a specific market (useful for checkout address forms)
const { data: marketCountries } = await client.markets.countries.list('mkt_xxx')
// Get a single country with states
const usa = await client.countries.get('US', {
expand: ['states'],
})
console.log(usa.states) // [{ abbr: "CA", name: "California" }, ...]
# All countries
curl 'http://localhost:3000/api/v3/store/countries' \
-H 'X-Spree-Api-Key: pk_xxx'
# Countries in a specific market
curl 'http://localhost:3000/api/v3/store/markets/mkt_xxx/countries' \
-H 'X-Spree-Api-Key: pk_xxx'
# Get a country with states
curl 'http://localhost:3000/api/v3/store/countries/US?expand=states' \
-H 'X-Spree-Api-Key: pk_xxx'
const { data: locales } = await client.locales.list()
// [{ code: "en", name: "English" }, { code: "fr", name: "French" }, ...]
curl 'http://localhost:3000/api/v3/store/locales' \
-H 'X-Spree-Api-Key: pk_xxx'
const { data: currencies } = await client.currencies.list()
// [{ iso_code: "USD", name: "US Dollar", symbol: "$" }, { iso_code: "EUR", name: "Euro", symbol: "€" }, ...]
curl 'http://localhost:3000/api/v3/store/currencies' \
-H 'X-Spree-Api-Key: pk_xxx'