@dts-stn/react-router-i18n-routes

中文文档
1.0.1发布于 2026/10/19MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 2909

类型安全,为React Routers(帧模式)所翻译的(i18n)路由定义.

中文使用文档
文档目录34 节
  1. 为什么?
  2. 特征
  3. 目录
  4. 安装
  5. 所需资源
  6. 入境点
  7. 快开始
  8. 1. 确定路线
  9. 2. 用回放路由器登记路线
  10. 3. 连接、重新定向和切换语言
  11. 概念
  12. 页路由
  13. 布局路线
  14. 路径实例
  15. 食谱
  16. 设定 <html lang> 在根布局中
  17. 重定向 / 改为客家首选语言
  18. 用正确的语言显示404页
  19. 添加 hreflang sEO 的替代链接
  20. 支持三种或三种以上语言
  21. 切换语言时重新装入文档
  22. 构建特定应用链接组件
  23. 处理路由错误
  24. API 参考
  25. @dts-stn/react-router-i18n-routes
  26. @dts-stn/react-router-i18n-routes/react
  27. @dts-stn/react-router-i18n-routes/route-config
  28. 行为细节
  29. 路径匹配
  30. 路径生成
  31. 语言检测
  32. 财务问题
  33. 捐款
  34. 许可证

@dts-stn/ react-router-i18n-routes (英语)

npm version CI types: TypeScript license: MIT

类型安全, 翻译 URL for 反应路由器 框架模式.

申报每页一次,每种语言都有路径. 您可以得到 React 路由器路由配置, 本地化链接和 重新定向,语言检测,和一个语言切换器. 每个路由文件和语言都是字符串字元类型,所以 断开的链接是编译错误,而不是404.

const i18nRoutes = defineI18nRoutes([
  {
    id: 'CASE-0001',
    file: 'routes/case.tsx',
    paths: { en: '/en/case/:caseId', fr: '/fr/dossier/:caseId' },
  },
]);

const i18nRouting = createI18nRouting(i18nRoutes);

i18nRouting.getPath('routes/case.tsx', 'fr', { params: { caseId: '42' } }); // '/fr/dossier/42'
i18nRouting.translatePath('/en/case/42', 'fr'); // '/fr/dossier/42'
i18nRouting.getPath('routes/case.tsx', 'de'); // ❌ type error: 'de' is not a supported language
i18nRouting.getPath('routes/cases.tsx', 'en'); // ❌ type error: no such route file

为什么?

A 类 /:lang/... 当只有语言段更改时,前缀就足够了。 许多地点,包括政府驻地 官方语文规则、需要 完全翻译路径 相反: /en/dashboard 财务报告和审定财务报表 /fr/tableau-de-bord进行中 通过手工方式,每个语言登记每一页,保持路径同步,并重复绘图 每一个链接、方向和语言切换。 这个软件包保留了一个路线表,并构建了它以外的一切.

特征

  • 🗺️ 一个真理的来源. 每页声明一次,React路由器获得每个语言的一个路由.
  • 🔒 完全输入, 不 as const。 。 。 . 路由文件、身份证和语言被推断为文字结合。 未知的文件, 排版文件,编译时拒绝不支持的语言.
  • 🔗 链接和重定向. <I18nLink> 替换 <Link>,以及 redirect() 正在建设 Responses 用于装载器和 动作,有参数,搜索和散列.
  • 🌐 语言切换. <I18nLanguageSwitchLink> 链接到其它语言的当前页面并保留其 parms,搜索,和散列.
  • 🧭 URL匹配 . URL 使用 React Router 自身的排名映射回路由和语言, 所以静态片段总是 击败动态的.
  • 🗣️ 语言谈判. 语言来自 URL, 有可选的 Accept-Language 倒计时.
  • ✅ 失败的验证. 重复的ID或文件,缺少翻译,以及启动时抛出的路由ID相撞.
  • 🪶 小而可树. 仅限无害环境管理, sideEffects: false,没有运行时间依赖 超出它的同行,它的工作 与回放18和19以及回放路由器7和8.

目录

安装

npm install @dts-stn/react-router-i18n-routes
# or
pnpm add @dts-stn/react-router-i18n-routes
# or
yarn add @dts-stn/react-router-i18n-routes

所需资源

软件包版本需要时间
react-router^7.0.0 || ^8.0.0所有的东西
react>=18.0.0@dts-stn/react-router-i18n-routes/react
@react-router/dev^7.0.0 || ^8.0.0@dts-stn/react-router-i18n-routes/route-config

react 财务报告和审定财务报表 @react-router/dev 是可选的同伴。 只有当您使用需要的切入点时才安装它们 .

软件包是 仅限无害环境管理 并且需要20号或以后的节点。 类型推论依赖 const 类型参数, (中文(简体) ), 因此,需要TypeScript 5.0或更晚.

入境点

导入路径目录从
@dts-stn/react-router-i18n-routes路线定义, createI18nRouting()类型和错误任何地方(客户端和服务器)
@dts-stn/react-router-i18n-routes/react钩和连接组件反应组件
@dts-stn/react-router-i18n-routes/route-config转换为 React 路由器路由配置app/routes.ts

快开始

1. 确定路线

将定义保留在自己的模块中这样 app/routes.ts,组件、装载器和动作都可以导入.

// app/i18n-routes.ts
import type { I18nLanguageOf, I18nRouteFileOf } from '@dts-stn/react-router-i18n-routes';
import { createI18nRouting, defineI18nRoutes } from '@dts-stn/react-router-i18n-routes';

export const i18nRoutes = defineI18nRoutes([
  {
    id: 'HOME-0001',
    file: 'routes/index.tsx',
    paths: { en: '/en/', fr: '/fr/' },
  },
  {
    // A pathless layout route
    file: 'routes/protected/layout.tsx',
    children: [
      {
        id: 'DASH-0001',
        file: 'routes/protected/dashboard.tsx',
        paths: { en: '/en/dashboard', fr: '/fr/tableau-de-bord' },
      },
      {
        id: 'CASE-0001',
        file: 'routes/protected/case.tsx',
        paths: { en: '/en/case/:caseId', fr: '/fr/dossier/:caseId' },
      },
    ],
  },
]);

export const i18nRouting = createI18nRouting(i18nRoutes);

export type I18nRouteFile = I18nRouteFileOf<typeof i18nRoutes>;
// 'routes/index.tsx' | 'routes/protected/dashboard.tsx' | 'routes/protected/case.tsx'

export type Language = I18nLanguageOf<typeof i18nRoutes>;
// 'en' | 'fr'

2. 用回放路由器登记路线

// app/routes.ts
import type { RouteConfig } from '@react-router/dev/routes';
import { route } from '@react-router/dev/routes';

import { toRouteConfigEntries } from '@dts-stn/react-router-i18n-routes/route-config';

import { i18nRoutes } from './i18n-routes';

export default [
  route('/api/health', 'routes/api/health.ts'), // non-translated routes work as usual
  ...toRouteConfigEntries(i18nRoutes),
] satisfies RouteConfig;

[大 反应路由器的配置加载器不能解决路径的别名, 例如 ~/,所以导入定义到 app/routes.ts 和相对路径.

import {
  I18nLanguageSwitchLink,
  I18nLink,
  useIsCurrentRoute,
  useIsNavigatingTo,
  useLanguage,
} from '@dts-stn/react-router-i18n-routes/react';

import { i18nRouting } from '~/i18n-routes';

export function Navigation() {
  const { alternateLanguage } = useLanguage(i18nRouting);
  const isDashboard = useIsCurrentRoute(i18nRouting, 'routes/protected/dashboard.tsx');
  const isLoadingCase = useIsNavigatingTo(i18nRouting, 'routes/protected/case.tsx', { params: { caseId: '42' } });

  return (
    <nav>
      {/* Links to the current language by default */}
      <I18nLink routing={i18nRouting} file="routes/protected/dashboard.tsx" aria-current={isDashboard ? 'page' : undefined}>
        Dashboard
      </I18nLink>

      {/* Any React Router <Link> prop is forwarded */}
      <I18nLink
        routing={i18nRouting}
        file="routes/protected/case.tsx"
        params={{ caseId: '42' }}
        search="tab=notes"
        prefetch="intent"
      >
        Case 42 {isLoadingCase && '…'}
      </I18nLink>

      {/* The current page in the other language, with the same params, search, and hash */}
      <I18nLanguageSwitchLink routing={i18nRouting}>
        {alternateLanguage === 'fr' ? 'Français' : 'English'}
      </I18nLanguageSwitchLink>
    </nav>
  );
}
// app/routes/protected/layout.tsx
import { i18nRouting } from '~/i18n-routes';

import type { Route } from './+types/layout';

export function loader({ request }: Route.LoaderArgs) {
  if (!isSignedIn(request)) {
    const language = i18nRouting.getLanguage(request) ?? 'en';
    throw i18nRouting.redirect('routes/index.tsx', language);
  }
}

就是这样。 每个 file, (中文(简体) ), language,以及 params 以上值的键入 app/i18n-routes.ts。 。 。 .

概念

页路由

一个页面路由有一个 id,路径模块 file,以及每种语言的路径:

{ id: 'DASH-0001', file: 'routes/protected/dashboard.tsx', paths: { en: '/en/dashboard', fr: '/fr/tableau-de-bord' } }
  • file 是路由模块,相对于应用程序目录,如: app/routes.ts。这也是 查找密钥数字 : 链接、重定向和钩子是指其文件中的一页.
  • paths 使用 React 路由器路径语法:活性区段( R):caseId),可选部分(:tab?),和花板 (单位:千美元)*)所有作业. 每个页面路径必须声明 同一套语言。 。 。 .
  • id 必须是独一无二的。 React 路由器每个语言获得一条路由,并带有 id ${id}-${LANGUAGE} (单位:千美元)DASH-0001-EN, (中文(简体) ), DASH-0001-FR) (中文(简体) ). 把这些身份传递给 useRouteLoaderData(),或用 getI18nRouteId()。 。 。 .

布局路线

一个布局路线有一个 file 财务报告和审定财务报表 children 但是没有 id 或者说 paths。它会变成一个无路径回放路由器 layout() 路径 让孩子度过难关 <Outlet />,用于认证卫士、共享铬和共享 装载机 布局可以筑巢. 排版不能成为链接目标, 因此将排版文件传递到 getPath() 是类型 错误.

路径实例

createI18nRouting(i18nRoutes) 验证定义一次并返回 I18nRouting 对象,每个查找和 URL 构建器。 在模块级别创建并导入一次 无论需要什么 反应钩和组件 把它当作他们的第一个论据或 routing 道具 (英语).

食谱

设定 <html lang> 在根布局中

// app/root.tsx
import type { ReactNode } from 'react';

import { Links, Meta, Scripts, ScrollRestoration } from 'react-router';

import { useCurrentLanguage } from '@dts-stn/react-router-i18n-routes/react';

import { i18nRouting } from '~/i18n-routes';

export function Layout({ children }: { children: ReactNode }) {
  const language = useCurrentLanguage(i18nRouting) ?? 'en';

  return (
    <html lang={language}>
      <head>
        <Meta />
        <Links />
      </head>
      <body>
        {children}
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}

重定向 / 改为客家首选语言

在 i18n 路由旁注册一个平面索引路由,并谈判语言 Accept-Language 页眉 :

// app/routes.ts
export default [index('routes/language-redirect.ts'), ...toRouteConfigEntries(i18nRoutes)] satisfies RouteConfig;
// app/routes/language-redirect.ts
import { i18nRouting } from '~/i18n-routes';

import type { Route } from './+types/language-redirect';

export function loader({ request }: Route.LoaderArgs) {
  // The language of the URL path, then the Accept-Language header, then English
  const language = i18nRouting.getLanguage(request, { acceptLanguage: true }) ?? 'en';
  return i18nRouting.redirect('routes/index.tsx', language);
}

用正确的语言显示404页

getLanguage() 当没有页面路由匹配时, 返回到第一个路径段, 所以一个覆盖所有路由仍然知道 /fr/page-inexistante 法语:

// app/routes.ts
export default [...toRouteConfigEntries(i18nRoutes), route('*', 'routes/not-found.tsx')] satisfies RouteConfig;
// app/routes/not-found.tsx
export default function NotFound() {
  const language = useCurrentLanguage(i18nRouting) ?? 'en';
  return <h1>{language === 'fr' ? 'Page introuvable' : 'Page not found'}</h1>;
}
import { useLocation } from 'react-router';

import { i18nRouting } from '~/i18n-routes';

const ORIGIN = 'https://www.example.com';

export function AlternateLinks() {
  const { pathname } = useLocation();

  return i18nRouting.languages.map((language) => {
    const path = i18nRouting.translatePath(pathname, language);
    return path && <link key={language} rel="alternate" hrefLang={language} href={new URL(path, ORIGIN).href} />;
  });
}

渲染器 <AlternateLinks /> 内部 <head> 内 app/root.tsx。 。 。 .

支持三种或三种以上语言

alternateLanguage 仅适用于双语应用程序。 更多语言,列表 alternateLanguages 并传递每个 I18nLanguageSwitchLink数字 :

const LANGUAGE_NAMES = { en: 'English', fr: 'Français', es: 'Español' } as const;

export function LanguageMenu() {
  const { alternateLanguages } = useLanguage(i18nRouting);

  return (
    <ul>
      {alternateLanguages.map((language) => (
        <li key={language}>
          <I18nLanguageSwitchLink routing={i18nRouting} language={language}>
            {LANGUAGE_NAMES[language]}
          </I18nLanguageSwitchLink>
        </li>
      ))}
    </ul>
  );
}

I18nLanguageSwitchLink 套装 lang 财务报告和审定财务报表 hrefLang 编辑 <a>,所以屏幕阅读器宣告每个语言名称 对.

切换语言时重新装入文档

如果每个文档都装入过一次翻译( 例如, 服务器上创建的 i18next 实例), 则通过 reloadDocument 这样切换语言就可以完成一个完整的页面负载 :

<I18nLanguageSwitchLink routing={i18nRouting} reloadDocument>
  Français
</I18nLanguageSwitchLink>

捆绑 routing 和默认样式 :

import type { I18nLinkProps } from '@dts-stn/react-router-i18n-routes/react';
import { I18nLink } from '@dts-stn/react-router-i18n-routes/react';

import type { i18nRoutes } from '~/i18n-routes';
import { i18nRouting } from '~/i18n-routes';

export function AppLink(props: Omit<I18nLinkProps<typeof i18nRoutes>, 'routing'>) {
  return <I18nLink routing={i18nRouting} className="underline" {...props} />;
}
<AppLink file="routes/protected/dashboard.tsx">Dashboard</AppLink> // ✅
<AppLink file="routes/protected/dashbord.tsx">Dashboard</AppLink> // ❌ type error

用于非链接导航( U)navigate(), (中文(简体) ), <Form action>, (中文(简体) ), fetcher.submit()),使用时 useI18nPath() 建造道路.

处理路由错误

包扔出的每一个错误都是 I18nRoutingError 有机器可读 code数字 :

import { I18nRoutingError } from '@dts-stn/react-router-i18n-routes';

try {
  const { route, language, params } = i18nRouting.getRouteByPath(pathname);
} catch (error) {
  if (error instanceof I18nRoutingError && error.code === 'ROUTE_NOT_FOUND') {
    // ...
  }
  throw error;
}

这个 find* 方法返回 undefined 而不是扔, 这往往更简单.

API 参考

@dts-stn/react-router-i18n-routes

defineI18nRoutes(routes)

回返 routes 不变,按文字键入,无 as const 需要帮助。 使用它来声明路由表.

createI18nRouting(routes)

验证路径并返回一个 I18nRouting 举个例子 掷出 I18nRoutingError 有代码 INVALID_ROUTES 如果:

  • 两个页面路由共享 an id 或一个 file, (中文(简体) ),
  • 页面路由并非全部声明相同的语言,或者
  • 两个路由/语言对生成相同的React Router路由id. 例如,语言 en 财务报告和审定财务报表 EN 碰撞,这样 执行路由 PAGE 使用语言 fr-CA 和路线 PAGE-FR 使用语言 ca,两者均生成 PAGE-FR-CA。 。 。 .

I18nRouting

成员回返说明
routesT路线定义.
languagesLanguage[]支持的语言,按声明顺序排列.
getPath(file, language, options?)string本地化,根相通的路径. options数字 : params, (中文(简体) ), search (单位:千美元)string 或者说 URLSearchParams, (中文(简体) ), hash。 。 。 .
redirect(file, language, options?)Response重定向到 getPath()。 。 。 . options.init 设置状态( 默认) 302或全数 ResponseInit。 。 。 .
translatePath(pathname, language, options?)string | undefined匹配的页面路由在另一种语言中的路径,保留其参数(/en/case/42 → /fr/dossier/42) (中文(简体) ). options数字 : search, (中文(简体) ), hash。 。 。 .
getLanguage(resource, options?)Language | undefined路径名的语言, URL,或 Request。见 语言检测。 。 。 .
getAlternateLanguages(language)Language[]其他按声明顺序支持语言.
findRouteByPath(pathname){ route, language, params } | undefined将路径名匹配到页面路由和语言.
getRouteByPath(pathname){ route, language, params }与 findRouteByPath()但抛出 ROUTE_NOT_FOUND。 。 。 .
findRouteByFile(file)PageRoute | undefined文件的页面路由 。 接受任意字符串,以便测试未知值.
getRouteByFile(file)PageRoute已知文件的页面路由, 输入为准确路由 。 掷出 ROUTE_NOT_FOUND。 。 。 .

getI18nRouteId(id, language)

页面路由中的一种语言的回放路由器路由ID: getI18nRouteId('DASH-0001', 'fr') → 'DASH-0001-FR'。 。 。 .

negotiateLanguage(acceptLanguage, languages)

最佳支持语言 Accept-Language 页眉值,或 undefined。见 语言检测。 。 。 .

negotiateLanguage('fr-CA,fr;q=0.9,en;q=0.8', ['en', 'fr']); // 'fr'

isI18nPageRoute(value), (中文(简体) ), isI18nLayoutRoute(value)

为行走路线定义而设的护卫类型.

I18nRoutingError

包抛出的错误 。 内容 code 这是:

代码掷出时
INVALID_ROUTEScreateI18nRouting() 发现定义不一致.
ROUTE_NOT_FOUND没有页面路由匹配文件或路径名传递到一个 get* 方法.
LANGUAGE_NOT_DETERMINEDuseI18nPath() 或者说 I18nLink 得到没有 language 而当前 URL 没有.

类型

类型说明
I18nRoute<L>, (中文(简体) ), I18nPageRoute<L>, (中文(简体) ), I18nLayoutRoute<L>路由定义类型, 通用于语言联盟 L。 。 。 .
I18nPaths<L>{ [language]: path }。 。 。 .
I18nRouteFileOf<T>页面路由文件在 typeof routes。 。 。 .
I18nRouteIdOf<T>页面路由代码的结合.
I18nLanguageOf<T>宣布的语言联盟 每个 页面路由.
I18nPageRouteOf<T>页面路由定义的结合.
I18nPageRouteForFile<T, F>文件的页面路由 F (返回类型 getRouteByFile()) (中文(简体) ).
I18nRouting<T>, (中文(简体) ), I18nRouteMatch<T>路径实例和结果 findRouteByPath()。 。 。 .
I18nPathOptions, (中文(简体) ), I18nRedirectOptions, (中文(简体) ), I18nTranslatePathOptions, (中文(简体) ), I18nLanguageOptions联合国 I18nRouting 方法。 。 .
I18nRoutingErrorCode错误代码的结合.

类型帮助者也接受广泛的类型,例如 I18nRoute<'en' | 'fr'>[]。对于这些,文件和身份证决心 string 和声明的联盟的语言.

@dts-stn/react-router-i18n-routes/react

每个钩子和元件都把路由实例当作它的第一论据(呼克)或 routing 道具(组件). 全体人员 他们从React路由器读取当前位置,所以必须在路由器内渲染出.

useLanguage(routing)

回返 { currentLanguage, alternateLanguage, alternateLanguages } 用于当前位置. alternateLanguage 设定 只有另外一种语言,即双语语言.

useCurrentLanguage(routing)

当前位置的语言,或 undefined (单位:千美元)routing.getLanguage(pathname)) (中文(简体) ).

useI18nRouteMatch(routing)

{ route, language, params } 用于当前位置,或 undefined (单位:千美元)routing.findRouteByPath(pathname)) (中文(简体) ).

useI18nPath(routing, file, options?)

routing.getPath(),与 options.language 默认为当前语言。 掷出 LANGUAGE_NOT_DETERMINED 若为 两者皆无。 用它来 navigate(), (中文(简体) ), <Form action>,其他需要路径而不是链接的任何东西.

useLanguageSwitchPath(routing, language?)

当前页 language (默认:替代语言),保留其参数,搜索和散列. 回返 undefined 在i18n路线之外.

useIsCurrentRoute(routing, file, options?)

当前位置是否 file任何语言的页面路线。 与 options.params,匹配的路径的参数 也必须平等。 用它来 aria-current="page"。 。 。 .

useIsNavigatingTo(routing, file, options?)

是否导航到 file页面路由正在装入 . options.language 默认为当前语言,并且 options.params 还比较了匹配路线的参数. 用于待定指标。 需要数据路由器 (框架模式, createBrowserRouter(),或 createMemoryRouter()) (中文(简体) ).

对于两者 useIsCurrentRoute() 财务报告和审定财务报表 useIsNavigatingTo()数字 :

  • file 也许 undefined (结果就是 false)),所以你可以从其组件中无条件称呼它们 链接并不总是 i18n 路由.
  • options.params 仅比较匹配的路由本身的参数, 这样您就可以通过完整 useParams() 对象.

反应路由器 <Link> 谁 to 道具替换为 routing, (中文(简体) ), file选择 language, (中文(简体) ), params, (中文(简体) ), search,以及 hash。语言默认为当前语言。 每一个 <Link> 道具,包括 ref, (中文(简体) ), prefetch,以及 viewTransition页:1.

未设置的回放路由器 <Link> 改为 useLanguageSwitchPath(),与 lang 财务报告和审定财务报表 hrefLang 设置到目标语言。 内容 to 道具替换为 routing 和可选 language。 所有其他 道具,包括 ref 财务报告和审定财务报表 reloadDocument页:1 它在i18n路线之外没有任何东西.

@dts-stn/react-router-i18n-routes/route-config

导出说明
toRouteConfigEntries(routes)将路由定义转换为 React Router 路由配置条目, 递归式 .
toPageRouteConfigEntries(pageRoute)将一个页面路由转换为每个语言的一个条目,以便在树外注册.

此切入点仅取决于 @react-router/dev/routes,因此从 app/routes.ts。 。 。 .

行为细节

路径匹配

findRouteByPath(), (中文(简体) ), translatePath(), (中文(简体) ), getLanguage(),而钩子与路由器的路径名匹配 matchRoutes() 跨越每一页路线和语言。 结果:

  • 静态片段胜过动态片段, 动态片段胜过平板, 不管宣布的顺序,
  • 随从的鞭打,是被忽视的,
  • %- 编码路径名被解码,以及
  • 路径名称与应用程序相对 basename。 。 。 .

路径生成

getPath() 使用响应路由器 generatePath()因此:

  • 缺少所需的抛出物,
  • 接后鞭打被去除(/en/ → /en, (中文(简体) ),
  • 结果总是从 /,即使没有一条道路被宣布(en/about → /en/about链接 从未相对于当前 URL 解析,以及
  • 静态片段、搜索和散列按申报方式返回(/fr/à-propos) (中文(简体) ).

redirect() %- encode 非 ASCII 字符 Location 页眉 (e)/fr/%C3%A0-propos)并留有 逃逸率不变.

语言检测

getLanguage(resource) 按顺序尝试 :

  1. 匹配页面路由的语言,
  2. 第一个路径段,如果它是一个支持的语言(/fr/anything → fr),以及
  3. 仅使用 { acceptLanguage: true } (单位:千美元) Request,则 Accept-Language 标题, 使用 negotiateLanguage()。 。 。 .

negotiateLanguage() 尝试下行质量顺序的偏好, 链接保持标题顺序 。 确切地说, 大小写不敏感匹配获胜。 要不然就比较初级亚种,所以 fr-CA 匹配 fr 财务报告和审定财务报表 fr 匹配 fr-CA。 。 。 . 条目 q=0,则 * 通配符,以及错误的条目被忽略.

饼干,会话,用户偏好被故意留给应用程序处理. 先读一下,然后回到 getLanguage()。 。 。 .

财务问题

它能翻译我的内容吗? 没有。 它只处理URL. 与任何翻译库(i18next, react-intl,Lingui,.)对等,并传入语言 从 useCurrentLanguage() 或者说 getLanguage()。 。 。 .

一个页面能否只用一种语言存在? 不是作为i18n路由:每个页面路由必须声明每种语言,这保证了语言切换器总是 有目标 使用 React 路由器自行注册的单语页 route() 内 app/routes.ts。 。 。 .

我可以用一个 /:lang/... 样式而不是翻译路径 ? 对 道路是简单的线条,所以 { en: '/en/about', fr: '/fr/about' } 和被翻译的子弹一样有效.

它是否在声明式或数据模式下工作(无 app/routes.ts{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? 核心入站和回放钩与任何路由器配合. /route-config 专门针对框架模式,以及 useIsNavigatingTo() 需要数据路由器。 在其他模式中,从 i18nRoutes 与 getI18nRouteId()。 。 。 .

为什么路由识别像 DASH-0001-EN? 吗? 反应路由器每条路由需要独有的ID,每一页成为每条语言的一个路由. 使用您喜欢的任何 ID 方案 大写后缀为后缀.

捐款

欢迎提出问题和拉动请求。 见 捐款额 用于开发设置和发布过程.

许可证

麻省理工学院

版本与发布记录

@dts-stn/react-router-i18n-routes 共发布 3 个版本,首次发布于 2026/10/19;过去 12 个月发布了 3 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.0.1latest2026/10/1925 天前
1.0.02026/10/1925 天前
0.0.0-stage2026/10/1925 天前

关于 @dts-stn/react-router-i18n-routes 的常见问题

@dts-stn/react-router-i18n-routes 是什么?

类型安全,为React Routers(帧模式)所翻译的(i18n)路由定义.

如何安装 @dts-stn/react-router-i18n-routes?

在项目目录运行 npm install @dts-stn/react-router-i18n-routes,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react-router(^7.0.0 || ^8.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@dts-stn/react-router-i18n-routes 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@dts-stn/react-router-i18n-routes 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@dts-stn/react-router-i18n-routes 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@dts-stn/react-router-i18n-routes 可以商用吗?

@dts-stn/react-router-i18n-routes 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@dts-stn/react-router-i18n-routes 的下载量有多少?

根据 npm 官方下载统计,@dts-stn/react-router-i18n-routes 在 2026/10/13 – 2026/11/11 这 30 天内被下载 2,909 次,日均约 97 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@dts-stn/react-router-i18n-routes 还在维护吗?

最新版本 1.0.1 发布于 2026/10/19(25 天前);至今共发布 3 个版本,其中过去 12 个月发布了 3 个;首次发布于 2026/10/19。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。