The plugin is deeply integrated with Modern.js routing system, supporting language path prefixes and automatic path redirection.
When localePathRedirect is set to true, the plugin will automatically add language prefixes to URLs and handle path redirection when switching languages.
Configuration:
i18nPlugin({
localeDetection: {
localePathRedirect: true,
languages: ['zh', 'en'],
fallbackLanguage: 'en',
// Optional: ignore automatic redirection for certain routes
ignoreRedirectRoutes: ['/api', '/admin'],
},
});Some routes (such as API routes, static resources, etc.) don't need language prefixes. You can use the ignoreRedirectRoutes configuration to ignore automatic redirection for these routes:
i18nPlugin({
localeDetection: {
localePathRedirect: true,
languages: ['zh', 'en'],
fallbackLanguage: 'en',
// String array: supports exact match and prefix match
ignoreRedirectRoutes: ['/api', '/admin', '/static'],
// Or use function for more flexible judgment
ignoreRedirectRoutes: pathname => {
return pathname.startsWith('/api') || pathname.startsWith('/admin');
},
},
});For more details, please refer to the ignoreRedirectRoutes configuration in the Locale Detection documentation.
After enabling path redirection, you need to add :lang dynamic parameter to the route configuration.
When using convention-based routing, you need to create a [lang] directory under the routes/ directory to represent the language parameter:
routes/
├── [lang]/
│ ├── layout.tsx # Layout component
│ ├── page.tsx # Home page
│ ├── about/
│ │ └── page.tsx # About page
│ └── contact/
│ └── page.tsx # Contact pageroutes/[lang]/layout.tsx:
import { Outlet } from '@modern-js/runtime/router';
export default function Layout() {
return <Outlet />;
}routes/[lang]/page.tsx:
export default function Home() {
return <div>Home</div>;
}routes/[lang]/about/page.tsx:
export default function About() {
return <div>About</div>;
}routes/[lang]/contact/page.tsx:
export default function Contact() {
return <div>Contact</div>;
}Generated Route Structure:
/:lang → Home page
/:lang/about → About page
/:lang/contact → Contact pageWhen accessing / or /about, it will automatically redirect to /en or /en/about (using the default language).
If using custom routing (modern.routes.ts), you need to add :lang dynamic parameter in the route configuration:
import {
BrowserRouter,
Route,
Routes,
Outlet,
} from '@modern-js/runtime/router';
function App() {
return (
<BrowserRouter>
<Routes>
{/* Add :lang parameter */}
<Route path=":lang" element={<Outlet />}>
<Route index element={<Home />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
</Route>
</Routes>
</BrowserRouter>
);
}Convention-based routing will automatically generate corresponding routes based on the file structure. It's recommended to use convention-based routing. Only use custom routing when special route control is needed.
The I18nLink component is provided by @modern-js/plugin-i18n and automatically adds the current language prefix to paths.
import { I18nLink } from '@modern-js/plugin-i18n/runtime';
function Navigation() {
return (
<nav>
<I18nLink to="/">Home</I18nLink>
<I18nLink to="/about">About</I18nLink>
<I18nLink to="/contact">Contact</I18nLink>
</nav>
);
}When current language is en:
<I18nLink to="/"> → Actual link: /en<I18nLink to="/about"> → Actual link: /en/aboutWhen current language is zh:
<I18nLink to="/"> → Actual link: /zh<I18nLink to="/about"> → Actual link: /zh/aboutI18nLink automatically handles language prefixes, no need to add them manually:
// ✅ Correct: No need to manually add language prefix
<I18nLink to="/about">About</I18nLink>
// ❌ Wrong: Don't manually add language prefix
<I18nLink to="/en/about">About</I18nLink>I18nLink accepts all Link component props and additionally supports:
interface I18nLinkProps {
/** Target path (no need to include language prefix) */
to: string;
/** Child elements */
children: React.ReactNode;
/** Other Link component props */
[key: string]: any;
}Example:
<I18nLink to="/about" replace>
About
</I18nLink>
<I18nLink to="/contact" state={{ from: 'home' }}>
Contact
</I18nLink>