Internationalization
Choose your default language, replace product copy, and publish paired content.
MuseMVP includes English and Chinese. Start by choosing your default language, then put your own wording over the template defaults without editing them.
Before You Start
Have a running app. UI copy is shared in packages/i18n; long-form docs, blog, legal, and changelog content belongs to each app's content/ folder.
1. Choose Your Default Language
In the selected app's .env.local, set:
NEXT_PUBLIC_DEFAULT_LOCALE="en"Use zh for Chinese. Restart dev and rebuild deployed apps after changing this public setting. The default language uses unprefixed public URLs: English default means / in English and /zh in Chinese; Chinese default means / in Chinese and /en in English.
packages/config/src/i18n.ts contains each locale's product metadata, docs title, and currency. Edit those entries for your product as described in Brand Settings.
2. Replace a UI String
Open packages/i18n/src/translations/en/mvp.json and zh/mvp.json. Merge this into the English file:
{
"home": {
"hero": {
"mainTitle1": "Acme",
"mainTitle2": "Your next product starts here"
}
}
}Use the same keys with Chinese text in the Chinese file. The existing Hero.tsx reads these keys, so refreshing the homepage will show your copy. For another component, inspect its useTranslations() or getTranslations() keys before adding an override.
Keep default.json unchanged. mvp.json replaces matching fields, while unspecified fields keep their defaults. Arrays are replaced as a whole, not appended. Existing content in mvp.json should be merged, not overwritten.
3. Publish Bilingual Content
Create paired *.en.mdx / *.zh.mdx under your app's content/docs, posts, legal, or changelog. Keep localized category metadata paired as meta.en.json / meta.zh.json. Edit source files; dev/build regenerates .source/.
If you maintain both apps, check page/content differences with pnpm apps:parity. Its --write option copies eligible files from Node to Workers, so inspect the changes before applying it. Shared translation JSON does not need copying between apps.
Check Your Result
- Open the default public URL and switch to the other language.
- Confirm homepage, navigation, metadata, and changed content use the intended language.
- Sign in and check the language on account pages as well.
- Run
pnpm type-checkand your selected app build after changing message structure or content.
Common Problems
| Problem | Fix |
|---|---|
| Override has no effect | Check the component's exact namespace/key and JSON nesting |
| Only one language changed | Add the same key paths to both mvp.json files |
| A translated list loses default items | Arrays replace the entire list; provide the full desired array |
| Missing copy appears in another language | Default-locale fallback can fill gaps; complete both translations rather than relying on fallback |
Adding Another Language
Extend locale enums and metadata, shared messages and types, routing, content sources, and paired navigation metadata. This is a development change rather than adding one JSON file. The message loader is packages/i18n/src/lib/messages.ts; it deep-merges locale defaults and overrides and fills non-default-locale gaps using the configured default language. Keep packages/i18n/src/types.ts compatible with new message trees.