Currency
Multi-currency on the same shop, with a runtime currency switcher
A shopper can switch currency while staying on the same shop and domain. Only the prices re-resolve: the SDK sends the chosen currency on every catalog request, and the backend either returns a stored per-currency price or converts from the shop's default currency (CNB for CZK shops, ECB/Frankfurter otherwise, with an optional safety margin).
The SDK owns the active currency, persists it to a cookie (so SSR and reloads
keep it), and refetches prices when it changes. You do not thread currency
through your components by hand.
useCurrency
import { useCurrency } from '@behio/storefront-sdk/react';
function Example() {
const { currency, effectiveCurrency, setCurrency, currencies, defaultCurrency } = useCurrency();
return (
<select value={effectiveCurrency ?? ''} onChange={(e) => setCurrency(e.target.value)}>
{currencies.map((c) => (
<option key={c} value={c}>{c}</option>
))}
</select>
);
}| Field | Description |
|---|---|
currency | The actively selected currency, or undefined when none chosen yet. |
effectiveCurrency | The currency actually applied: selection, else the default. |
setCurrency(code | undefined) | Switch currency. Persists, refetches prices. undefined resets to default. |
currencies | Available currencies (from the shop's supportedCurrencies). |
defaultCurrency | The default currency (provider override, else the shop default). |
isLoading | True while the shop info (currency list) is loading. |
CurrencySwitcher
A drop-in switcher wired to useCurrency. It renders nothing when the shop has
only one currency (override with showWhenSingle).
import { CurrencySwitcher } from '@behio/storefront-sdk/react';
<CurrencySwitcher labels={{ CZK: 'Kč', EUR: '€' }} className="my-select" />Fully custom UI via a render-prop, while the SDK still owns the state:
<CurrencySwitcher>
{({ currencies, value, setCurrency }) =>
currencies.map((c) => (
<button key={c} aria-pressed={c === value} onClick={() => setCurrency(c)}>
{c}
</button>
))
}
</CurrencySwitcher>Configuring the default and the list
BehioProvider lets you tune the behaviour:
<BehioProvider
apiKey={apiKey}
currency="CZK" // initial currency when none is chosen yet
defaultCurrency="CZK" // the "default" surfaced by the switcher
currencies={['CZK', 'EUR']} // curate the list (else: shop supportedCurrencies)
onCurrencyChange={(c) => {/* analytics, URL sync, ... */}}
persistCurrency // default true; cookie keeps the choice
currencyCookieName="behio_currency"
>
{children}
</BehioProvider>Approximate (converted) prices
When a price was FX-converted rather than stored for that currency, the
ProductPrice carries isApproximate: true plus fxSource, baseAmount and
baseCurrency. Surface a subtle hint for honesty:
{product.price.isApproximate && <span title={`from ${product.price.baseAmount} ${product.price.baseCurrency}`}>≈</span>}
{formatPrice(product.price.amount, product.price.currency)}Formatting prices
formatPrice formats an amount with proper per-currency decimals (whole amounts
show none, e.g. 1 499 Kč; fractional show two, e.g. 24,99 €) for a BCP-47
locale. It is server-safe (pure Intl, no React) and exported from both the
main entry and /react, so server components and client components format money
the same way:
import { formatPrice } from '@behio/storefront-sdk'; // server components / anywhere
// or
import { formatPrice } from '@behio/storefront-sdk/react'; // client components
formatPrice(1499, 'CZK'); // "1 499 Kč"
formatPrice(24.99, 'EUR', 'en'); // "€24.99"| Param | Description |
|---|---|
amount | The price amount (e.g. 1499, 24.99). |
currency | ISO 4217 code ("CZK", "EUR", "USD"). |
locale | BCP-47 locale ("cs", "en", …). Defaults to "cs". |
Cart re-pricing on switch (SDK 1.6.0)
Catalog prices are display; the cart is money. setCurrency from this hook
(and from <CurrencySwitcher/>) therefore also calls
client.cart.setCurrency(...) when a cart session exists, so the cart's line
prices are re-resolved server-side in the new currency and checkout charges
the amounts the shopper saw. Money is never FX-converted: if some cart item
has no price configured in the target currency, the cart keeps its previous
currency while the catalog still switches. See
Switch Cart Currency.
Server-side rendering
In server components, getBehio() reads the same currency cookie automatically,
so server-rendered prices already match the shopper's choice. You only pass a
currency explicitly when you want to force one.
import { getBehio } from '@behio/storefront-sdk/next';
const behio = await getBehio(); // currency from the cookie
const { data } = await behio.catalog.getProducts({ limit: 12 });