logo
  • 指南
  • 配置
  • 插件
  • API
  • 示例
  • 社区
  • Modern.js 2.x 文档
  • 简体中文
    • 简体中文
    • English
    • 开始
      介绍
      快速上手
      版本升级
      名词解释
      技术栈
      核心概念
      页面入口
      构建工具
      Web 服务器
      基础功能
      路由
      路由基础
      配置式路由
      数据管理
      数据获取
      数据写入
      数据缓存
      渲染
      服务端渲染(SSR)
      服务端流式渲染(Streaming SSR)
      渲染缓存
      静态站点生成(SSG)
      渲染预处理 (Render Preprocessing)
      样式开发
      引入 CSS
      使用 CSS Modules
      使用 CSS-in-JS
      使用 Tailwind CSS
      HTML 模板
      引用静态资源
      引用 JSON 文件
      引用 SVG 资源
      引用 Wasm 资源
      调试
      数据模拟(Mock)
      网络代理
      使用 Rsdoctor
      使用 Storybook
      测试
      Playwright
      Vitest
      Jest
      Cypress
      路径别名
      环境变量
      构建产物目录
      部署应用
      进阶功能
      使用 Rspack
      使用 BFF
      基础用法
      运行时框架
      扩展 BFF Server
      扩展一体化调用 SDK
      文件上传
      跨项目调用
      优化页面性能
      代码分割
      静态资源内联
      产物体积优化
      React Compiler
      提升构建性能
      浏览器兼容性
      配置底层工具
      源码构建模式
      服务端监控
      Monitors
      日志事件
      指标事件
      国际化
      基础概念
      快速开始
      配置说明
      语言检测
      资源加载
      路由集成
      API 参考
      高级用法
      最佳实践
      自定义 Web Server
      专题详解
      模块联邦
      简介
      开始使用
      应用级别模块
      服务端渲染
      部署
      集成国际化能力
      常见问题
      依赖安装问题
      命令行问题
      构建相关问题
      热更新问题
      已下线功能
      📝 编辑此页面
      上一页配置说明下一页资源加载

      #语言检测

      插件支持多种语言检测方式,可以组合使用以满足不同的业务需求。

      #检测方式

      #1. URL 路径检测(localePathRedirect)

      当 localePathRedirect 设置为 true 时,插件会从 URL 路径中检测语言。

      示例:

      • /zh/about → 检测到语言:zh
      • /en/about → 检测到语言:en
      • /about → 如果没有语言前缀,会重定向到默认语言路径

      配置:

      i18nPlugin({
        localeDetection: {
          localePathRedirect: true,
          languages: ['zh', 'en'],
          fallbackLanguage: 'en',
        },
      });

      路由配置(约定式路由):

      使用约定式路由时,需要在 routes/ 目录下创建 [lang] 目录来表示语言参数:

      routes/
      ├── [lang]/
      │   ├── layout.tsx    # 布局组件
      │   ├── page.tsx      # 首页
      │   └── about/
      │       └── page.tsx  # About 页面

      routes/[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>;
      }
      Info

      如果使用自定义路由(modern.routes.ts),需要在路由配置中添加 :lang 动态参数。约定式路由会自动根据文件结构生成对应的路由。

      #2. i18next 语言检测器

      当 i18nextDetector 设置为 true 时,会启用 i18next 的语言检测器,支持从以下位置检测语言:

      • Cookie:从 Cookie 中读取语言设置
      • LocalStorage:从浏览器 LocalStorage 中读取
      • 查询参数:从 URL 查询参数中读取(如 ?lng=en)
      • 请求头:从 HTTP 请求头中读取(如 Accept-Language)
      • HTML 标签:从 HTML 标签的 lang 属性读取
      • 子域名:从子域名中读取(如 en.example.com)

      配置:

      i18nPlugin({
        localeDetection: {
          i18nextDetector: true,
          detection: {
            order: ['cookie', 'querystring', 'header'],
            lookupCookie: 'i18next',
            lookupQuerystring: 'lng',
            lookupHeader: 'accept-language',
            caches: ['cookie'],
          },
        },
      });

      #3. 自定义检测配置

      通过 detection 选项可以自定义检测行为:

      i18nPlugin({
        localeDetection: {
          i18nextDetector: true,
          detection: {
            // 检测顺序
            order: ['path', 'cookie', 'querystring', 'header'],
      
            // Cookie 相关
            lookupCookie: 'i18next',
            cookieExpirationDate: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), // 1年后过期
            cookieDomain: '.example.com',
      
            // 查询参数相关
            lookupQuerystring: 'lng',
      
            // 请求头相关
            lookupHeader: 'accept-language',
      
            // 缓存配置
            caches: ['cookie', 'localStorage'],
          },
        },
      });

      #检测优先级

      插件的语言检测遵循以下优先级顺序(从高到低):

      1. SSR 数据(最高优先级):从 window._SSR_DATA 中读取服务端渲染时设置的语言,适用于 SSR 和 CSR 项目
      2. 路径检测:如果 localePathRedirect 为 true,从 URL 路径中检测语言前缀
      3. i18next 检测器:按照 detection.order 配置的顺序执行检测(Cookie、LocalStorage、查询参数、请求头等)
      4. 用户配置语言:使用 initOptions.lng 中配置的语言
      5. 回退语言:使用 fallbackLanguage 作为最终回退
      Info

      SSR 数据检测优先级最高,这是为了确保客户端能够使用服务端渲染时检测到的语言,避免客户端重新检测导致的语言闪烁问题。

      示例:

      // 配置的检测顺序(仅影响 i18next 检测器内部的优先级)
      detection: {
        order: ['path', 'cookie', 'querystring', 'header'],
      }
      
      // 实际检测流程:
      // 1. 首先检查 SSR 数据(window._SSR_DATA)
      // 2. 然后检查 URL 路径(如果启用 localePathRedirect)
      // 3. 然后按照 order 顺序检查 i18next 检测器:
      //    - Cookie
      //    - 查询参数
      //    - 请求头
      // 4. 然后使用 initOptions.lng(如果配置)
      // 5. 最后使用 fallbackLanguage

      #检测选项说明

      #order(检测顺序)

      指定 i18next 检测器内部的检测顺序,可选值:

      • path:从 URL 路径检测(需要 localePathRedirect 为 true)
      • querystring:从查询参数检测(如 ?lng=en)
      • cookie:从 Cookie 检测
      • localStorage:从 LocalStorage 检测(仅浏览器环境)
      • sessionStorage:从 SessionStorage 检测(仅浏览器环境)
      • navigator:从浏览器语言设置检测(仅浏览器环境)
      • htmlTag:从 HTML 标签的 lang 属性检测(仅浏览器环境)
      • header:从 HTTP 请求头检测(如 Accept-Language)
      • subdomain:从子域名检测(如 en.example.com)

      默认检测顺序:

      如果不配置 order,插件会使用以下默认顺序:

      order: [
        'querystring', // 查询参数优先级最高
        'cookie', // 然后是 Cookie
        'localStorage', // 然后是 LocalStorage
        'header', // 然后是请求头
        'navigator', // 然后是浏览器语言
        'htmlTag', // 然后是 HTML 标签
        'path', // 然后是路径
        'subdomain', // 最后是子域名
      ];
      Warning

      path 检测需要 localePathRedirect 为 true,localStorage、sessionStorage、navigator、htmlTag 仅在浏览器环境可用。

      Info

      注意:order 配置只影响 i18next 检测器内部的优先级。实际的检测优先级还包括 SSR 数据和路径检测,它们有更高的优先级(见上面的"检测优先级"章节)。

      #caches(缓存方式)

      指定检测到的语言应该缓存在哪里,可选值:

      • false:不缓存
      • ['cookie']:缓存到 Cookie
      • ['localStorage']:缓存到 LocalStorage(仅浏览器)
      • ['cookie', 'localStorage']:同时缓存到 Cookie 和 LocalStorage

      #lookupQuerystring、lookupCookie、lookupLocalStorage、lookupSession、lookupHeader

      指定从查询参数、Cookie、LocalStorage、SessionStorage 或请求头中读取语言时使用的键名:

      • lookupQuerystring:默认 'lng',例如 ?lng=en
      • lookupCookie:默认 'i18next'
      • lookupLocalStorage:默认 'i18nextLng'(仅浏览器环境)
      • lookupSession:SessionStorage 的键名(仅浏览器环境)
      • lookupHeader:默认 'accept-language'

      #lookupFromPathIndex

      指定从 URL 路径的哪个位置开始检测语言(当 order 中包含 'path' 时):

      • lookupFromPathIndex:路径段索引,默认为 0(第一个路径段)

      示例:

      // URL: /api/v1/en/users
      // 如果 lookupFromPathIndex = 2,则从第三个路径段('en')开始检测
      detection: {
        order: ['path'],
        lookupFromPathIndex: 2,
      }

      #cookieMinutes、cookieExpirationDate

      控制 Cookie 的过期时间:

      • cookieMinutes:Cookie 过期时间(分钟),默认 525600(1 年)
      • cookieExpirationDate:Cookie 过期日期(Date 对象),优先级高于 cookieMinutes

      示例:

      detection: {
        cookieMinutes: 60 * 24 * 7, // 7天后过期
        // 或
        cookieExpirationDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7天后过期
      }

      #ignoreRedirectRoutes

      指定哪些路由应该忽略自动语言重定向。这对于 API 路由、静态资源等不需要语言前缀的路径非常有用。

      配置方式:

      i18nPlugin({
        localeDetection: {
          localePathRedirect: true,
          languages: ['zh', 'en'],
          fallbackLanguage: 'en',
          // 字符串数组:支持精确匹配和前缀匹配
          ignoreRedirectRoutes: ['/api', '/admin', '/static'],
          // 或使用函数进行更灵活的判断
          ignoreRedirectRoutes: pathname => {
            return pathname.startsWith('/api') || pathname.startsWith('/admin');
          },
        },
      });

      匹配规则:

      • 字符串数组:支持精确匹配('/api')和前缀匹配('/api' 会匹配 /api 和 /api/users)
      • 函数:接收路径名(已去除语言前缀),返回 true 表示忽略重定向

      示例:

      // 忽略所有 API 路由和静态资源
      ignoreRedirectRoutes: ['/api', '/static', '/assets'];
      
      // 使用函数忽略所有以 /api 开头的路径
      ignoreRedirectRoutes: pathname => pathname.startsWith('/api');