Translations
The SHOPin storefront accelerator keeps locale strings in core/i18n (@core/i18n) and exposes them through the BFF where the storefront loads them.
Workspaces
@core/i18n— JSON per locale and shared language helpers.apps/bff— Registers locales and serves translation payloads to the presentation app (seesrc/i18n/i18n.service.ts).@config/constants— Locale lists and related settings (seesrc/i18n.ts); details in Config & constants.core/*(optional) — A dedicated package or module if you pull strings from an external provider; see Other workspaces and Data sources.
Add a new language
Locale file names and codes in examples below are illustrative—mirror whatever locales the repo already ships.
1. Add locale JSON
Add a file such as core/i18n/fr-FR.json next to existing locales (e.g. en-US.json, de-DE.json), matching their key structure.
2. Register in config
Update config/constants/src/i18n.ts so the new language appears in the supported locale list (and any default / routing rules your project uses).
3. Expose from the BFF
Update apps/bff/src/i18n/i18n.service.ts so the new JSON is imported and included in what the BFF returns to the frontend.
Add translation keys
Pick a namespace
Reuse existing top-level keys such as common, topBar, footer, product, plp when they fit. For a new area, add a new top-level namespace and use the same name across every locale file.
Update every locale
Edit each file under core/i18n (e.g. en-US.json, de-DE.json) so the new path exists everywhere with the right string per language.
Use in the storefront
Server — getTranslations from next-intl/server:
import { getTranslations } from 'next-intl/server'
const t = await getTranslations('product')
const label = t('buyBox.addToBasket')
Client — useTranslations from next-intl:
import { useTranslations } from 'next-intl'
const t = useTranslations('plp')
const label = t('filters.color')
For where UI code lives, see Component.
External translation source
To load copy from a CMS or translation API instead of or alongside static JSON:
-
Adapter — Add a NestJS-oriented module under
core/(or follow your existing provider pattern). See Data sources for how adapters and the factory fit together. -
Service — Fetch by locale (and namespace if applicable) and return data in the same shape as the static JSON so consumers stay unchanged.
-
Configuration — Let the BFF choose static vs external (env, feature flag, or factory branch)—aligned with Data sources and app config.
-
BFF — Extend
i18n.service.tsso it can use the external source when enabled, with fallback to@core/i18nfiles when the call fails or the integration is off.
Related
- Config & constants —
@config/constantsandi18n.ts - Data sources — BFF providers and factory
- Component — Presentation UI
- General workflow rules