This guide will help you quickly integrate internationalization functionality into your Modern.js project.
First, install the necessary dependencies:
pnpm add @modern-js/plugin-i18n i18next react-i18next
i18next and react-i18next are peer dependencies and need to be installed manually.
modern.config.tsimport { appTools, defineConfig } from '@modern-js/app-tools';
import { i18nPlugin } from '@modern-js/plugin-i18n';
export default defineConfig({
server: {
publicDir: './locales', // Required: specify the resource file directory
},
plugins: [
appTools(),
i18nPlugin({
localeDetection: {
localePathRedirect: true, // Enable path redirection
languages: ['zh', 'en'], // Supported language list
fallbackLanguage: 'en', // Default language
},
backend: {
enabled: true, // Enable backend resource loading
// loadPath defaults to '/locales/{{lng}}/{{ns}}.json', usually no need to modify
// Note: You can also omit 'enabled' and just configure 'loadPath' or 'addPath',
// or omit backend config entirely to let the plugin auto-detect locales directory
},
}),
],
});
server.publicDir is a required configuration used to specify the actual location of resource files. Even when using the default loadPath, this configuration is still required.
src/modern.runtime.tsCreate the src/modern.runtime.ts file and configure i18n runtime options:
import { defineRuntimeConfig } from '@modern-js/runtime';
import i18next from 'i18next';
// It's recommended to create a new i18next instance to avoid using the global default instance
const i18nInstance = i18next.createInstance();
export default defineRuntimeConfig({
i18n: {
i18nInstance: i18nInstance,
initOptions: {
fallbackLng: 'en',
supportedLngs: ['zh', 'en'],
},
},
});
modern.runtime.ts is a runtime configuration file used to configure i18next initialization options. Even for the most basic configuration, it's recommended to create this file to ensure the plugin works correctly.
It's recommended to use i18next.createInstance() to create a new instance instead of directly using the default exported i18next. This avoids global state pollution and ensures each application has an independent i18n instance.
Create a locales folder in the project root and organize resource files by language:
locales/
├── en/
│ └── translation.json
└── zh/
└── translation.jsonlocales/en/translation.json:
{
"hello": "Hello",
"world": "World",
"welcome": "Welcome to Modern.js"
}locales/zh/translation.json:
{
"hello": "你好",
"world": "世界",
"welcome": "欢迎使用 Modern.js"
}import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
import { useTranslation } from 'react-i18next';
function App() {
const { language, changeLanguage, supportedLanguages } = useModernI18n();
const { t } = useTranslation();
return (
<div>
<h1>{t('welcome')}</h1>
<p>Current language: {language}</p>
<div>
{supportedLanguages.map(lang => (
<button
key={lang}
onClick={() => changeLanguage(lang)}
disabled={lang === language}
>
{lang}
</button>
))}
</div>
</div>
);
}
export default App;