LingoProvider は、現在のロケールとメッセージマップを保持する React コンテキストです。アプリのルートで一度だけラップすれば、その配下ではどこからでも useLingo() を呼び出して文字列を翻訳したり、ロケールのメタデータを参照したりできます。
基本的な使い方#
tsx
import { LingoProvider } from "@lingo.dev/react";
import messages from "./locales/es.json";
<LingoProvider locale="es" messages={messages}>
<App />
</LingoProvider>Props#
| Prop | 型 | 必須 | 説明 |
|---|---|---|---|
locale | string | はい | BCP-47 タグ。たとえば "en"、"es"、"ar-SA"。すべてのフォーマット処理と RTL 判定の基準になります。 |
messages | Messages | いいえ | ハッシュキーを使った翻訳セットです。デフォルトは {} で、すべてソースにフォールバックします。 |
children | ReactNode | はい | アプリ本体です。 |
Messages は単なる Record<string, string> です。つまり、CLI が locales/<locale>.json に書き出すものと同じ形です。
プロバイダーのネスト#
プロバイダーはネストできます。ネストしたプロバイダーのロケールが親と同じか、異なるかで挙動が変わります。
同じロケール — メッセージはマージされる#
tsx
<LingoProvider locale="es" messages={sharedMessages}>
{/* Route-scoped messages override shared on collision; missing keys fall through to shared. */}
<LingoProvider locale="es" messages={dashboardMessages}>
<Dashboard />
</LingoProvider>
</LingoProvider>ルートに共通の「シェル」用翻訳を置いたまま、ルート単位でバンドルを分けたいときに便利です。
異なるロケール — 独立して動作#
tsx
<LingoProvider locale="es" messages={esMessages}>
<Header />
<LingoProvider locale="ar-SA" messages={arMessages}>
{/* This subtree is entirely Arabic; the parent's es messages are NOT visible. */}
<ArabicEmbed />
</LingoProvider>
</LingoProvider>アプリ全体は別の言語で動かしつつ、特定のコンポーネントだけを固定言語で表示したいときに便利です。たとえば、引用、埋め込み、プレビューペインなどに向いています。
実行時にロケールを切り替える#
locale は React の state として扱えます。これを変更すると、その配下にあるすべての useLingo() 利用側が、新しいロケールとメッセージバッグで再レンダリングされます。
tsx
function AppRoot() {
const [locale, setLocale] = useState("en");
const [messages, setMessages] = useState({});
async function switchTo(next: string) {
const next_messages = await import(`./locales/${next}.json`);
setLocale(next);
setMessages(next_messages.default);
}
return (
<LingoProvider locale={locale} messages={messages}>
<LocaleSwitcher current={locale} onSelect={switchTo} />
<App />
</LingoProvider>
);
}Next.js では、@lingo.dev/react-next の useLocaleSwitch() を使うのがおすすめです。ルーターに応じたロケール変更と永続化をまとめて処理してくれます。
コンテキストから参照できるもの#
useLingo() は、現在の Lingo オブジェクトを返します。text() と rich() に加えて、次の情報も含まれます。
locale— 渡した BCP-47 文字列direction—"ltr"または"rtl"。Intl.Locale.textInfoで計算され、既知の RTL 言語リストをフォールバックとして使いますscript— たとえば"Latn"、"Cyrl"、"Arab"region— たとえば"US"、"DE"、"SA"
これらは、条件に応じたレイアウト切り替え(RTL でのアイコン反転など)や分析用タグ付けに便利です。追加で解析する必要はありません。
よくあるミス#
<LingoProvider>を付け忘れる。useLingo()は、その外側で使うと例外を投げます。エラーメッセージにはプロバイダーを追加するよう案内が出ます。テスト中にこのエラーが出る場合は、空のmessagesを渡したテスト用プロバイダーで render をラップすると、アサーションが安定します。- 非同期で読み込んだメッセージをそのまま渡す。
messagesには同期値が必要です。親コンポーネント側で promise を解決し(Suspense または state を使用)、その結果を渡してください。 localeだけ切り替えてmessagesを更新しない。 プロバイダーは 2 つの props が揃って渡される前提で動作します。同じuseState更新で一緒に切り替えないと、新しいロケールに古い翻訳が一瞬表示されることがあります。
