🔦

React-i18nextで翻訳用テキストの一部をハイライトする方法

2025/02/11に公開

背景

react-i18next で国際化対応する時に出会った課題です。

課題

国際化対応では通常、辞書となるjsonファイルを用意し、その中に翻訳用のテキストを記述します。

en.json

{
  "welcome": "Welcome!"
}

ja.json

{
  "welcome": "ようこそ"
}

これらのテキストをカスタマイズ(例:動的変数の埋め込みやリンクの埋め込みなど)する場合、少々工夫が必要です。

私の場合、テキストの一部分をハイライトしたい場面に出会いました。

翻訳用のテキスト全てをハイライトしたい場合は、通常styleを当てた span などのタグで囲うことができるので比較的容易です。しかしこのタグの部分が国際化対応したい文の一部である場合、どうすればいいか分からず途方に暮れてしまいました。

例としては下記の辞書のnameの部分を黄色くハイライトしたいようなケースです。

en.json

{
  "greeting": "Hello, {{name}}!"
}

ja.json

{
  "greeting": "こんにちは、{{name}}さん!"
}

Setup, Version等

ライブラリの説明やsetupの実施方法については、すでに詳しく取り上げてくれている先人がいますので割愛します。

使用ライブラリのバージョンは下記です。

  • react: ^19.0.0
  • react-dom: ^19.0.0
  • react-i18next: ^15.4.0
  • i18next: ^24.2.2

結論

react-i18nextに用意されているTransコンポーネントのcomponents propertyを使うことで解決できます!

<Trans
  i18nKey="greeting"
  values={{ name: "Test User" }}
  components={{
    highlight: <span style={{ backgroundColor: "yellow" }} />
  }}
/>

下記がコードの全貌です。

import React from "react";
import { useTranslation, Trans } from "react-i18next";

function App() {
  const { t, i18n } = useTranslation();
  const changeLanguage = (lang: string) => {
    i18n.changeLanguage(lang);
  };

  return (
    <div
      style={{
        display: "flex",
        justifyContent: "center",
        flexDirection: "column",
        width: "800px",
        marginX: "auto",
      }}
    >
      <div style={{ marginBottom: "1rem" }}>
        <button
          onClick={() => changeLanguage("ja")}
          style={{
            fontSize: "16px",
            margin: "0 5px",
            cursor: "pointer",
            width: 100,
            height: 40,
          }}
        >
          日本語
        </button>
        <button
          onClick={() => changeLanguage("en")}
          style={{
            fontSize: "16px",
            margin: "0 5px",
            cursor: "pointer",
            width: 100,
            height: 40,
          }}
        >
          English
        </button>
      </div>

      <h2>{t("welcome")}</h2>
      <p>
        <Trans
          i18nKey="greeting"
          values={{ name: "Test User" }}
          components={{
            highlight: <span style={{ backgroundColor: "yellow" }} />
          }}
        />
      </p>
    </div>
  );
}

export default App;

辞書ファイルの方も忘れずに設定するようにしましょう。highlightというキーが Trans コンポーネントのcomponents propertyで指定したものに対応します。

en.json

{
  "welcome": "Welcome!",
  "greeting": "Hello, <highlight>{{name}}</highlight>!"
}

ja.json

{
  "welcome": "ようこそ",
  "greeting": "こんにちは、<highlight>{{name}}</highlight>さん!"
}

英語の表示

alt text

日本語の表示

alt text

GitHubで編集を提案

Discussion