路由集成

启用语言路径前缀

设置 localePathRedirect: true 后,插件会接管 URL 中的语言识别和跳转,具体做以下四件事:

  1. 识别 URL 里的语言前缀:访问 /zh/detail 时,插件从路径中提取 zh 作为当前语言
  2. 无前缀路径自动重定向:访问 /detail 时,先通过 detector 检测语言,检测不到则用 fallbackLanguage,然后重定向到 /en/detail/zh/detail
  3. 切换语言时同步更新 URL:当前在 /en/detail,调用 changeLanguage('zh') 后 URL 自动变为 /zh/detail,而不只是改 i18next 内部的语言状态
  4. 避免路径被重复检测:插件会自动从 i18next detector 的 order 中移除 path,因为路径语言识别已由插件自己处理,不需要 i18next 再检测一遍
// modern.config.ts
i18nPlugin({
  localeDetection: {
    localePathRedirect: true,
    languages: ['zh', 'en'],
    fallbackLanguage: 'en',
  },
});

效果:

访问路径结果
/about重定向到 /en/about
/en/about正常访问,语言为 en
/zh/about正常访问,语言为 zh

某些路径(如 API 路由、静态资源)不需要语言前缀,可以通过 ignoreRedirectRoutes 跳过重定向,详见语言检测 → ignoreRedirectRoutes

路由配置

启用 localePathRedirect 后,需要在路由中添加 [lang] 动态参数来接收语言前缀。

约定式路由

routes/ 目录下创建 [lang] 目录:

routes/
└── [lang]/
    ├── layout.tsx    ← 可在此读取 params.lang
    ├── page.tsx
    └── about/
        └── page.tsx

生成的路由结构:

/:lang          → page.tsx
/:lang/about    → about/page.tsx

如果需要在布局或页面中读取当前语言参数:

// routes/[lang]/layout.tsx
import { Outlet, useParams } from '@modern-js/runtime/router';

export default function Layout() {
  const { lang } = useParams();
  // lang 为当前 URL 中的语言代码,如 'en'、'zh'
  // 通常不需要手动使用,useModernI18n() 会自动管理
  return <Outlet />;
}

自定义路由

Info

自定义路由仅在不使用 Modern.js 约定路由系统时才需要。大多数项目推荐使用约定式路由。

如果使用自定义路由文件(modern.routes.ts),需要手动添加 :lang 参数:

// modern.routes.ts
import { Route, Routes, Outlet } from '@modern-js/runtime/router';

export default function App() {
  return (
    <Routes>
      <Route path=":lang" element={<Outlet />}>
        <Route index element={<Home />} />
        <Route path="about" element={<About />} />
      </Route>
    </Routes>
  );
}

I18nLink 是语言感知的链接组件,会自动在目标路径前添加当前语言前缀,无需手动拼接。

import { I18nLink } from '@modern-js/plugin-i18n/runtime';

function Navigation() {
  return (
    <nav>
      <I18nLink to="/">首页</I18nLink>
      <I18nLink to="/about">关于</I18nLink>
      <I18nLink to="/contact" replace>联系</I18nLink>
    </nav>
  );
}

当前语言为 en 时:

<I18nLink to="/about">  →  实际链接:/en/about
<I18nLink to="/">       →  实际链接:/en

注意事项:

// ✅ 正确:不需要手动添加语言前缀
<I18nLink to="/about">关于</I18nLink>

// ❌ 错误:不要手动添加语言前缀,会导致 /en/en/about
<I18nLink to="/en/about">关于</I18nLink>

I18nLink 继承自 @modern-js/runtime/routerLink 组件,支持 replacestateclassName 等所有标准 Link props,完整 Props 类型见 API 参考