文档中心开发者技术手册全球多语言体系与双向排版 (RTL/LTR)
next-intl + Strapi CMS + Medusa v2

国际化多语言体系与原生 RTL/LTR 双向排版架构

基于 next-intl 构建的强固多语言工程体系,无缝支持全球 7 种主流语言,具备智能语种重定向与边缘级缓存支持。

Download Base English Translation Template (default.json)

To add any new language (such as Turkish, French, German, or Spanish), download this complete base English template containing all 863 standard storefront keys and translate its values:

Download default.json Template (42 KB)
Important translation rule: Expressions inside curly braces such as {name}, {discount}, {total} and HTML tags like <tos> are dynamic system interpolation variables and must NOT be modified or translated.

1. 基于 URL 前缀的语言路由体系 (Locale Routing)

为了达成无可挑剔的跨国搜索引擎优化(SEO),每个页面地址均天然包含语言代码前缀(例如 /zh 或 /en)。

src/app/[countryCode]/layout.tsx
typescript
import { NextIntlClientProvider } from "next-intl"
import { getMessages } from "next-intl/server"
import { isRtlLocale } from "@lib/util/is-rtl"
export default async function StoreLayout({
children,
params,
}: {
children: React.ReactNode
params: Promise<{ countryCode: string }>
}) {
const { countryCode } = await params
const messages = await getMessages()
const isRtl = isRtlLocale()
const dir = isRtl ? "rtl" : "ltr"
return (
<html lang={countryCode} dir={dir}>
<body className={isRtl ? "font-vazirmatn" : "font-inter"}>
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
)
}

2. CSS 逻辑属性样式策略 (Logical Properties)

全站采用 Tailwind CSS 现代化逻辑属性类(ms、me、start、end),无论从左至右还是从右至左排版,界面布局均自适应镜像反转。

messages/default.json
json
{
"HomePage": {
"title": "Medusa Store",
"subtitle": "Best products for you"
},
"Cart": {
"title": "Cart",
"checkout": "Go to checkout"
},
"Product": {
"actions": {
"add_to_cart": "Add to cart",
"out_of_stock": "Out of stock"
}
}
}

环境变量配置说明 (Environment Variables)

若要在 Storefront 前端项目中配置默认语言与国家地区,请在 .env 文件中定义如下变量:

.env (多语言与默认地区配置)
bash
# 若请求头中未检测到地理位置时的备用国家代码
NEXT_PUBLIC_DEFAULT_REGION=us
# 商城默认启动语言
DEFAULT_LOCALE=en-US
  • NEXT_PUBLIC_DEFAULT_REGION: 当缺失地理位置请求头(如 x-vercel-country)时生效的默认国家代码(跨国站点建议设为 us,针对中国境内市场可设为 CN)。
  • DEFAULT_LOCALE: 决定前台默认呈现的主语言(简体中文站点建议设为 zh-CN,或国际站点设为 en-US)。

Adding a New Language Without Writing Code (No-Code)

Strapi Storefront Settings + Medusa Locales

The Loomix platform uses a dynamic, multi-layered architecture for localization, allowing store managers to add complete languages in under 3 minutes without rebuilding or restarting containers:

1. Prepare and Translate the JSON File

Download the base default.json file above, rename it following standard BCP-47 naming (e.g., tr-TR.json for Turkish or fr-FR.json for French), and translate the string values.

2. Upload in Strapi CMS

Log in to Strapi Admin and navigate to Content Manager > Single Types > Storefront Setting:
• Under the Translations section, click Add an entry.
• In the language field, enter the standard 4-letter compound code (e.g., tr-TR).
• In the file field, upload and select the translated JSON file.
• Click Save and then Publish to invalidate the storefront cache via on-demand ISR webhooks.

3. Local Source Synchronization (Optional)

In Strapi Admin, open the Storefront management page. Under the Translations & Locales card, click Sync Translations from Strapi. This downloads uploaded files directly into store/messages/ and regenerates the local language registry.

Is a production rebuild required after adding a language?
No, absolutely not! The Next.js storefront dynamically fetches uploaded translation files from Strapi and performs a runtime deepMerge over base strings, making changes live instantly without rebuild or downtime.

4. Activate Header Flag Selector (Medusa Admin)

To display the country flag and language name in the storefront header dropdown, navigate to Medusa Admin > Settings > Store / Locales and add the new locale (e.g., code tr-TR with name Turkish).

Why is the new language not immediately visible? (1-Hour Cache)
Next.js aggressively caches the /store/locales API response in memory for 1 hour (revalidate: 3600) for high throughput. If the flag does not appear immediately, simply run the following command on your VPS to clear the cache:
docker compose restart storefront

Resolving HTTP 403 Forbidden on Translation Sync

If clicking Sync Translations from Strapi outputs the following error:

[Translation Sync] Strapi endpoint returned HTTP 403. Falling back to local messages directory.

Root Cause: In Strapi, the Public role does not have read permissions granted for the storefront-settings endpoint by default, causing requests to be rejected with status 403.

Resolution Steps (Under 30 Seconds):

  1. Log into Strapi Admin and go to Settings (bottom gear icon) > USERS & PERMISSIONS PLUGIN > Roles.
  2. Click on the Public role to open permission settings.
  3. Under content types, find Storefront-setting and check the find permission.
  4. Under the Plugins list, navigate to Media Library and ensure the find permission is checked (to permit downloading translation files).
  5. Click Save in the top right corner, then return to the Storefront page and click Sync again.