Command Palette

Search for a command to run...

Guides › Storefront Localization Engine

Storefront Localization Engine

Use market-aware storefront translations, language defaults, and market overrides through the canonical engine.

Storefront Localization Engine

Commercit now has one canonical storefront localization engine.

It is responsible for:

  • shop languages
  • language assignment to markets
  • one primary language per market
  • language-default translations
  • optional market + language overrides
  • translated storefront routes and handles
  • CSV import/export for storefront localization inventory

This engine is storefront-only.

It covers:

  • theme storefront sections
  • app storefront sections
  • checkout storefront copy
  • products
  • collections
  • pages
  • blog posts
  • menus
  • SEO fields
  • translated handles and full paths

It does not translate the admin UI.

Mental Model

Use this model:

  1. The shop defines supported languages.
  2. Markets are assigned one or more of those languages.
  3. Each market has one primary language.
  4. Content can have:
    • a language-default translation
    • an optional market-specific override for that same language

Example:

  • global English product title: Free shipping on orders over £50
  • Greece market English override: Free shipping in Greece on orders over €50

That is the intended model:

  • same language
  • different market copy when needed

Fallback Order

At storefront runtime, Commercit resolves translatable values in this order:

  1. market + language override
  2. language default translation
  3. base storefront value

This applies to:

  • content fields
  • storefront UI strings
  • checkout storefront strings
  • translated handles and paths

What App and Theme Authors Should Do

There are two different things:

  1. Packaged storefront UI copy
  2. Merchant-translated storefront content

For packaged storefront UI copy, authors should:

  • declare extracted descriptors with defineMessages(...) and optional one-off msg(...)
  • pass messageCatalog to the surface definition
  • use t(...)
  • use formatPrice(...), formatDate(...), and formatNumber(...)
  • avoid hardcoded currency formatting and locale-blind Intl.* calls in surfaces
  • keep packaged defaults language-based in code
  • let merchants manage market-specific overrides through the localization engine inventory

For merchant storefront content, authors should:

  • treat the base content editor as the source of truth for the default value
  • let the platform localization engine resolve translated/overridden storefront output
  • not build their own translation storage layer for storefront content

Theme SDK Usage

import { defineMessages, defineSection, formatPrice, t } from '@commercit/theme-sdk'
import { Card, CardContent, CardHeader, CardTitle } from '@commercit/theme-sdk/ui'

const copy = defineMessages('promo', {
  heading: 'Free shipping',
  body: 'Orders over {threshold} ship free.',
})

export default defineSection({
  messageCatalog: Object.values(copy),
  component: function PromoStrip() {
    return (
      <Card>
        <CardHeader>
          <CardTitle>{t(copy.heading)}</CardTitle>
        </CardHeader>
        <CardContent>
          <p>{t(copy.body, { threshold: formatPrice(50) })}</p>
        </CardContent>
      </Card>
    )
  },
})

App SDK Usage

import { defineMessages, defineSection, t, useLocale, useMarket } from '@commercit/app-sdk'
import { Card, CardContent, CardHeader, CardTitle } from '@commercit/app-sdk/ui'

const copy = defineMessages('reviews', {
  heading: 'What shoppers think',
})

export default defineSection({
  messageCatalog: Object.values(copy),
  component: function ReviewsSummary() {
    const locale = useLocale()
    const market = useMarket()

    return (
      <Card>
        <CardHeader>
          <CardTitle>{t(copy.heading)}</CardTitle>
        </CardHeader>
        <CardContent>
          <p>
            locale: {locale} · market: {market.marketHandle ?? 'default'} · currency: {market.currencyCode}
          </p>
        </CardContent>
      </Card>
    )
  },
})

Available Runtime Helpers

Theme authors can use these from @commercit/theme-sdk or @commercit/theme-sdk/ui. App authors can use these from @commercit/app-sdk/ui.

Available helpers:

  • useTranslations()
  • t(descriptor, params?)
  • useLocale()
  • useMarket()
  • useCurrency()
  • useDirection()
  • formatPrice(amount, options?)
  • formatDate(value, options?)
  • formatNumber(value, options?)

These helpers use host-resolved storefront context:

  • locale
  • languageCode
  • direction
  • marketId
  • marketHandle
  • currencyCode
  • timezone

Manifest Requirements for Apps

Apps with UI surfaces must declare:

{
  "i18n": {
    "default_locale": "en",
    "supported_locales": ["en", "el"]
  }
}

And their UI modules must emit an extracted messageCatalog.

The validator enforces:

  • i18n.default_locale is required for UI apps
  • every storefront UI surface must emit an extracted message catalog
  • raw user-facing literals outside defineMessages(...) / msg(...) are rejected for canonical storefront surfaces

Merchant Translation Flow

Commercit ships the engine and basic merchant tooling:

  • language management
  • market-language assignment
  • primary language per market
  • storefront translation inventory
  • CSV import/export

The core platform does not try to be a machine translation provider.

That is intentional:

  • core = localization engine
  • apps = translation providers and workflows later

What Not to Do

Do not:

  • create your own storefront translation tables
  • hardcode currency symbols
  • call raw Intl.NumberFormat or Intl.DateTimeFormat for storefront surfaces when the shared helpers already cover the use case
  • treat markets as app-owned configuration

Markets and languages remain native platform systems. Themes and apps are consumers of that system.