文字列の翻訳

文字列を国際化する方法

概要

このガイドでは、useGT() フックを使ってReactアプリの文字列を国際化する方法を説明します。

以下の内容を取り上げます:

useGT() フックを使用するタイミング

useGT() フックの使い方

変数の使用方法

よくある落とし穴


useGT() フックを使うタイミング

useGT() フックは、文字列を翻訳するために使用できる React フックです。

ほとんどの場合、<T> コンポーネントを使用できます。 ただし、JSX が適切でない場合には、useGT() フックを使用できます。

useGT() フックの方が適している場合の例は以下の通りです:

  • placeholdertitle 属性のように、厳密に文字列が求められるプロパティの場合。
  • 文字列が大きなオブジェクトの一部である場合。例えば:
const user = {
  title: 'Mr.',
  name: 'John',
  description: 'John is a software engineer at General Translation',
}

この場合、description プロパティのみを翻訳する必要があります。

可能な限り、<T> コンポーネントを使用してください。 <T> コンポーネントは JSX コンテンツの翻訳を可能にし、文字列を翻訳する推奨方法です。


useGT() フックの使い方

useGT() フックは、<GTProvider> の内部で呼び出す必要があります。

文字列を翻訳するには、フックから返される関数にそのまま文字列を渡すだけです。

const translate = useGT();
translate('Hello, world!');

従来の i18n ライブラリとは異なり、useGT() フックでは関数に key を渡す必要はありません。 代わりに、文字列を直接関数に渡します。

つまり、辞書を使う必要がありません!

変数の使用

多くの場合、変数を含む文字列を翻訳する必要があります。

例えば、数値を含む文字列を翻訳する必要がある場合があります。

変数を追加するには、{variable}のようにプレースホルダーとして変数を文字列に追加し、 フックから返される関数の第二引数としてオブジェクトを渡すだけです。

const price = 100;
const translate = useGT();
translate('There are {count} items in the cart', { count: 10 });

{count}プレースホルダーはcount変数の値に置き換えられます。

これにより、翻訳で動的な値を表示することができます。

APIの詳細については、APIリファレンスを参照してください。

gt-reactはICUメッセージフォーマットをサポートしており、変数をフォーマットすることも可能です。

const translate = useGT();
translate('There are {count, plural, =0 {no items} =1 {one item} other {{count} items}} in the cart');

ICUメッセージフォーマットは変数をフォーマットする強力な方法です。 詳細については、ICUメッセージフォーマットのドキュメントを参照してください。


  1. コンポーネント内で文字列を翻訳する
import { useGT } from 'gt-react';

export default function MyComponent() {
  const t = useGT();
  return (
    <div>
      <h1>{t('Hello, world!')}</h1>
    </div>
  )
}
export default function MyComponent() {
  return (
    <div>
      <h1>Hello, world!</h1>
    </div>
  )
}
  1. 変数を含む文字列を翻訳する
import { useGT } from 'gt-react';

export default function MyComponent() {
  const t = useGT();
  const count = 10;
  return (
    <div>
      <h1>{t('There are {count} items in the cart', { count })}</h1>
    </div>
  )
}
export default function MyComponent() {
  const count = 10;
  return (
    <div>
      <h1>There are {count} items in the cart</h1>
    </div>
  )
}
  1. オブジェクトの一部を翻訳する
import { useGT } from 'gt-react';

export default function MyComponent() {
  const t = useGT();
  const users = [
    {
      name: 'John',
      description: t('John is a software engineer at General Translation'),
    },
    {
      name: 'Jane',
      description: t('Jane is a software engineer at Google'),
    },
  ]
  return (
    <div>
      {users.map((user) => (
        <div key={user.name}>
          <h1>{user.name}</h1>
          <p>{user.description}</p>
        </div>
      ))}
    </div>
  )
}
export default function MyComponent() {
  const users = [
    {
      name: 'John',
      description: 'John is a software engineer at General Translation',
    },
    {
      name: 'Jane',
      description: 'Jane is a software engineer at Google',
    },
  ]
  return (
    <div>
      {users.map((user) => (
        <div key={user.name}>
          <h1>{user.name}</h1>
          <p>{user.description}</p>
        </div>
      ))}
    </div>
  )
}
  1. 共有定数を翻訳する
src/llms.ts
// Custom function to get LLM data with translations
export function getLLMData(t: (content: string) => string) {
  return [
    {
      name: 'GPT-4.1',
      id: 'gpt-4.1',
      description: t('GPT-4.1 is a large language model developed by OpenAI'),
    },
    {
      name: 'Claude 3.7 Sonnet',
      id: 'claude-3-7-sonnet',
      description: t('Claude 3.7 Sonnet is a large language model developed by Anthropic'),
    },
  ]
}
import { getLLMData } from './llms';
import { useGT } from 'gt-react';

export default function MyComponent() {
  const t = useGT();
  const llms = getLLMData(t);
  return (
    <div>
      {llms.map((llm) => (
        <div key={llm.id}>
          <h1>{llm.name}</h1>
          <p>{llm.description}</p>
        </div>
      ))}
    </div>
  )
}
src/llms.ts
export const llms = [
  {
    name: 'GPT-4.1',
    id: 'gpt-4.1',
    description: 'GPT-4.1 is a large language model developed by OpenAI',
  },
  {
    name: 'Claude 3.7 Sonnet',
    id: 'claude-3-7-sonnet',
    description: 'Claude 3.7 Sonnet is a large language model developed by Anthropic',
  },
]
import { llms } from './llms';

export default function MyComponent() {
  return (
    <div>
      {llms.map((llm) => (
        <div key={llm.id}>
          <h1>{llm.name}</h1>
          <p>{llm.description}</p>
        </div>
      ))}
    </div>
  )
}

この最後の例では、llms配列を翻訳付きでデータを返す関数に変換しました。 データを返す関数にt関数を渡しています。

別の方法として、llms配列をカスタムフックに変換することもできます。 ただし、これは推奨されません。useGT()フックの使用方法に非常に注意する必要があり、 Reactのルールに違反しないようにする必要があるためです。


よくある落とし穴

動的コンテンツの翻訳

すべての文字列はビルド時に判明している必要があります。

つまり、実行時に生成または取得される動的コンテンツは翻訳できません。

これは、たとえ文字列であっても変数も含まれます。

export default function MyComponent() {
  const [dynamicContent, setDynamicContent] = useState('Hello, world!');
  const t = useGT();
  return (
    <div>
      <h1>{t(dynamicContent)}</h1> // This will not work
    </div>
  )
}

CLIツールは、動的コンテンツを翻訳しようとした場合に警告を表示します


次のステップ

このガイドはいかがですか?