如何在 TanStack Start v1 中标记多语言内容

为不同语言的文本添加标记以提升无障碍体验

问题

当页面包含多种语言的文本时,浏览器和辅助技术会默认所有内容都使用页面声明的语言。例如,配置为英语的屏幕阅读器会用英语发音规则来朗读法语短语、西班牙语书名或德语公司名,导致依赖音频的用户听到难以理解的内容。浏览器会应用错误的拼写检查规则,将拼写正确的外语单词标记为错误。排版引擎也会错误处理不同语言的标点和空格规范。

这些问题会为视障用户带来障碍,也会让所有使用辅助技术的用户更难理解内容。当外语词汇频繁出现,或内容中包含较长的外语段落时,问题会进一步加剧。

解决方案

为每一处外语文本添加 HTML lang 属性,标明其正确的语言,指导辅助技术临时切换发音引擎。可以在包裹外语内容的元素上添加语言属性,以便对其进行不同的样式或处理。这样可以让屏幕阅读器正确朗读每种语言,也让浏览器对每个片段应用合适的排版和拼写检查规则。

步骤

1. 创建用于标记外语文本的组件

将外语文本包裹在带有 lang 属性的元素中,建议使用语义化文本元素而不是 span,因为部分屏幕阅读器会忽略 span 上的 lang 属性。

interface ForeignTextProps {
  lang: string;
  children: React.ReactNode;
}

export function ForeignText({ lang, children }: ForeignTextProps) {
  return <i lang={lang}>{children}</i>;
}

i 元素用于表示不同语气或语调的文本,包括其他语言的术语,并确保屏幕阅读器能够识别语言属性。

2. 使用组件标记内嵌外语短语

将组件应用于内容中的外语单词或短语,并指定相应的语言代码。

import { ForeignText } from "~/components/ForeignText";

export default function ArticlePage() {
  return (
    <article>
      <p>
        The book <ForeignText lang="es">Cien años de soledad</ForeignText> is
        considered a masterpiece of magical realism.
      </p>
      <p>
        She said <ForeignText lang="fr">c'est la vie</ForeignText> and walked
        away.
      </p>
    </article>
  );
}

在相应元素上添加 lang 属性可指示辅助技术临时切换语言,从而确保发音准确。

3. 标记较长的外语段落

对于多句外语内容,请直接在块级元素上应用 lang 属性。

export default function QuotePage() {
  return (
    <article>
      <p>The original German text reads:</p>
      <blockquote lang="de">
        <p>Die Grenzen meiner Sprache bedeuten die Grenzen meiner Welt.</p>
      </blockquote>
      <p>
        This translates to: The limits of my language mean the limits of my
        world.
      </p>
    </article>
  );
}

lang 属性几乎可以与所有 HTML 元素一起使用,只需将该属性添加到如 blockquote 等元素上,即可轻松在页面内切换语言。

4. 查询内容所需的语言代码

请使用 IANA 语言子标签注册表中的语言标签,可通过非官方的 Language Subtag Lookup 工具进行查询。

export default function MultilingualPage() {
  return (
    <div>
      <p>
        Common examples: <ForeignText lang="fr">bonjour</ForeignText> (French),
        <ForeignText lang="de">Gesundheit</ForeignText> (German),
        <ForeignText lang="ja">ありがとう</ForeignText> (Japanese),
        <ForeignText lang="ar">شكرا</ForeignText> (Arabic)
      </p>
    </div>
  );
}

对于任何语言,优先使用两字母代码,只有在没有两字母代码时才使用三字母代码。