如何在 React Router v7 中设置文档语言

为浏览器和屏幕阅读器声明页面语言

问题

网页需要向浏览器和辅助技术声明其主要语言。如果没有明确的语言声明,屏幕阅读器会默认使用用户的系统语言,这可能会在内容语言不同的情况下导致发音错误。浏览器无法提供准确的翻译功能,因为它们必须猜测源语言。搜索引擎在为正确的语言受众索引页面时会遇到困难,从而降低了用户在该语言中搜索时的可发现性。

解决方案

在根 <html> 元素上设置 lang 属性以声明文档的主要语言。此属性接受一个有效的语言代码,用于告知浏览器、屏幕阅读器和搜索引擎内容使用的语言。当语言被明确声明时,辅助技术可以应用正确的发音规则,浏览器可以提供适当的翻译选项,搜索引擎可以为正确的语言受众索引页面。

步骤

1. 确定当前的区域设置

app/root.tsx 中的根路由负责渲染根 HTML 文档。如果您的应用程序使用基于区域设置的路由(例如 /:locale/... 模式),请从路由参数中提取区域设置。否则,使用默认的区域设置。

import { useParams } from "react-router";

export default function Root() {
  const params = useParams();
  const locale = params.locale || "en";

  return (
    <html lang={locale}>
      <head>
        <meta charSet="utf-8" />
      </head>
      <body>
        <h1>内容</h1>
      </body>
    </html>
  );
}

这段代码从 URL 中读取区域设置(如果存在),并在没有区域设置参数时回退到英语。

2. 将区域设置代码映射到语言标签

如果您的应用程序使用的自定义区域设置标识符与标准语言标签不同,请创建一个映射函数将它们转换为有效的 BCP 47 语言代码。

function getLanguageTag(locale: string): string {
  const languageMap: Record<string, string> = {
    en: "en",
    "en-US": "en-US",
    es: "es",
    fr: "fr",
    de: "de",
    ja: "ja",
    "zh-CN": "zh-Hans",
    "zh-TW": "zh-Hant",
  };

  return languageMap[locale] || "en";
}

这确保了即使您的路由使用简化的区域设置代码,lang 属性也能接收到有效的语言标签。

3. 将语言标签应用于 HTML 元素

使用映射的语言标签作为根组件中 <html> 元素的 lang 属性值。

import { useParams } from "react-router";

function getLanguageTag(locale: string): string {
  const languageMap: Record<string, string> = {
    en: "en",
    es: "es",
    fr: "fr",
    de: "de",
  };
  return languageMap[locale] || "en";
}

export default function Root() {
  const params = useParams();
  const locale = params.locale || "en";
  const lang = getLanguageTag(locale);

  return (
    <html lang={lang}>
      <head>
        <meta charSet="utf-8" />
      </head>
      <body>
        <h1>内容</h1>
      </body>
    </html>
  );
}

lang 属性现在反映了当前的语言环境,当用户在特定语言的路由之间导航时会自动更新。