Shopping experiences rarely live in one market, one language, or one audience. You sell into different regions, in different currencies, in different languages — and you probably want the same platform to serve B2B and B2C, retail and wholesale, brand A and brand B, without maintaining a parallel project for each. Frontic is built for that from day one. This page explains how scopes, regions, locales, currencies, and domains compose into a multi-market stack — and how you write your blocks and storages once while the stack delivers the right variant to each caller.Documentation Index
Fetch the complete documentation index at: https://docs.frontic.com/llms.txt
Use this file to discover all available pages before exploring further.
The four axes
Scope
Who is asking. B2B, B2C, wholesale, different brands, different
loyalty tiers. Scopes let you ship variations of the same content to
different audiences without branching your data model.
Region
Where they are. A region is a geographic market — United States,
Germany, Europe, DACH. Each region carries its own currency and its
own set of supported locales.
Locale
What language they speak. Locales are language codes (
en, de,
fr-CA). Translatable fields in your storages return the variant
matching the resolved locale.Domain
How they arrived. Domains map URLs (e.g.
www.demo-shop.com/de,
b2b.demo-shop.com/en) to a specific scope + region + locale
combination. The mapping is how request context gets resolved
automatically for public traffic.Configure your axes
The big idea: one project serves every market. You don’t spin up a separate Frontic project per country, per language, or per brand. Pair the project with the codebase that renders it — generated client, release history, and deploy pipeline all line up against that one repo — and compose markets inside the project via regions, locales, currencies, and scopes. Parallel projects for parallel markets fight the grain.Define regions
Add the regions you serve — “US”, “Germany”, “Europe (ex-DE)”,
“UK”. Each region is a geographic unit with:
- a default locale
- a supported locale list
- a currency the stack uses for pricing responses in that region
Define locales
Add the languages you support —
en-US, en-GB, de-DE, fr-CA.
Locales are global to the project; regions reference them. You can
have locales that aren’t available in every region (e.g. fr is
available in Europe and Canada but not in the US).Define scopes
Most projects start with a single default scope —
public. Add
scopes if you need audience variants: b2b, wholesale, staff,
loyalty-gold. Scoped fields in your storages (see below) are only
returned when the caller’s scope matches.Storage field flags
On Data Storage fields, three flags let you control how a field behaves across the four axes:Translatable
The field holds a different value per locale. A translatable
name field on a product storage has a German variant, an English
variant, a French variant, etc. The stack serves the right one based
on the caller’s resolved locale.Scoped
The field is only available in specific scopes. A scoped
wholesalePrice field exists only in the wholesale scope. Callers
in the public scope never see it, and listings can’t filter on it
from the public scope.Array
The field holds multiple values. Tag lists, multi-image galleries,
multi-category assignments. Combines with Translatable and Scoped —
you can have a translatable array field of tags that differ per
language and per scope.
Translatable: true, Scoped: false, Shared Across Variants: true for a product description that’s the same for every variant but different per language — and the stack takes care of the rest.
Example: a product across markets
Here’s how a singleProducts Data Storage serves a multi-market catalogue:
| Field | Flags | How it behaves |
|---|---|---|
name | Translatable, Shared across variants | Same across variants of one product, different per locale |
description | Translatable, Shared across variants | As above |
price | (variant-level, built-in) | Same record across scopes/locales, but auto-returned in the caller’s region currency |
wholesalePrice | Scoped to b2b | Returned only to B2B callers; invisible to public scope |
swatchImage | (per-variant) | Variant-specific media, returned based on which variant is resolved |
seo | Translatable, Shared across variants | SEO composite — title, description, keywords resolve per locale |
Shared blocks and listings
Because Detail Blocks, Search Listings, and Page URLs all read from a context-aware Data Storage, you don’t need market-specific API surfaces. A singleProductHero block serves every market. A single ProductList listing serves every market. A single /products/:slug page resolves to different records per domain — but you wrote the page once.
That’s the payoff of commerce-native infrastructure: the hard problems of multi-market commerce are solved in the stack, not in your code. You spend your time on the experience, not on plumbing locale-aware data fetching into every component.
Common patterns
Same catalogue, different languages
Same catalogue, different languages
One region, multiple locales. Mark all user-facing text fields
Translatable. The same product records serve every language because
the stack substitutes the localized field values at response time.
B2B and B2C on the same project
B2B and B2C on the same project
Two scopes:
public and b2b. B2B-only fields (wholesale pricing,
bulk discounts, tax-exempt flags) are Scoped to b2b. B2B domains
map callers into the b2b scope. Public domains stay in public.
One set of blocks, one set of listings, two fully-different experiences.Multiple brands on one platform
Multiple brands on one platform
One scope per brand. Each brand gets its own domain(s) mapping into
its scope. Shared primitives (product categories, shared content)
stay unscoped and are reused; brand-specific content lives in scoped
fields or scoped Data Storages.
Rolling out a new language
Rolling out a new language
Add the locale to the project, add it to the regions it’s available
in, let translators fill in the translatable fields over time.
Blocks and listings keep working — callers in other locales aren’t
affected — and the moment a translation lands, it flows through.
Related
Product Models
How products and variants compose with the scope/region/locale axes.
URLs, Redirects & SEO
How domains translate into actual URLs — and how URL history survives
every release.
Request Context
The full picture of how scope, region, and locale get resolved per
request.