文字列
useGT と getGT を使ってプレーンテキストの文字列を国際化する方法
文字列の翻訳は、JSX を使わずにテキストの翻訳へ直接アクセスでき、属性、オブジェクトのプロパティ、プレーンテキストの値に最適です。同期コンポーネントでは useGT、非同期コンポーネントでは getGT を使用します。
同期処理と非同期処理の使い分け
クイックスタート
同期的コンポーネント
import { useGT } from 'gt-next';
function MyComponent() {
const t = useGT();
return (
<input
placeholder={t('メールアドレスを入力してください')}
title={t('メールアドレス入力欄')}
/>
);
}非同期コンポーネント
import { getGT } from 'gt-next/server';
async function MyServerComponent() {
const t = await getGT();
return (
<input
placeholder={t('メールアドレスを入力してください')}
title={t('メールアドレス入力欄')}
/>
);
}文字列翻訳を使うタイミング
JSX ではなくプレーンテキストが必要な場合に、文字列翻訳が適しています。
HTML 属性
const t = useGT();
<input
placeholder={t('商品を検索...')}
aria-label={t('商品検索')}
title={t('カタログを検索')}
/>オブジェクトのプロパティ
const t = useGT();
const user = {
name: 'John',
role: 'admin',
bio: t('React開発経験5年のソフトウェア開発者'),
status: t('現在プロジェクト対応可能')
};設定と定数
const t = useGT();
const navigationItems = [
{ label: t('ホーム'), href: '/' },
{ label: t('製品'), href: '/products' },
{ label: t('お問い合わせ'), href: '/contact' }
];<T> を使うべき場面
JSX コンテンツには、<T> コンポーネントを使用します。
// ✅ JSXコンテンツには<T>を使用
<T><p><strong>当ストア</strong>へようこそ!</p></T>
// ✅ プレーンテキストにはt()を使用
<input placeholder={t('商品を検索')} />変数の使用
基本のvariables
プレースホルダーを動的なvalueに置き換えます:
const t = useGT();
const itemCount = 5;
// プレースホルダーを含む文字列
const message = t('カートに{count}個のアイテムがあります', { count: itemCount });
// 結果: "カートに5個のアイテムがあります"複数のvariables
const t = useGT();
const order = { id: 'ORD-123', total: 99.99, date: '2024-01-15' };
const confirmation = t(
'注文 {orderId} (${total}) を {date} に承りました',
{
orderId: order.id,
total: order.total,
date: order.date
}
);ICUメッセージ形式
高度なフォーマットには、ICU 構文を使用します:
const t = useGT();
translate('{count, plural, =0 {カートに商品はありません} =1 {カートに商品が1点あります} other {カートに{count}点の商品があります}}', { count: 10 });ICU Message Format については、Unicode のドキュメントをご覧ください。
例
フォーム入力欄
import { useGT } from 'gt-next';
function ContactForm() {
const t = useGT();
return (
<form>
<input
type="email"
placeholder={t('メールアドレスを入力')}
aria-label={t('メールアドレス入力欄')}
/>
<textarea
placeholder={t('プロジェクトについてお聞かせください...')}
aria-label={t('プロジェクト概要')}
/>
<button type="submit">
{t('送信')}
</button>
</form>
);
}ナビゲーション メニュー
import { useGT } from 'gt-next';
function Navigation() {
const t = useGT();
const menuItems = [
{ label: t('ホーム'), href: '/', icon: 'home' },
{ label: t('企業情報'), href: '/about', icon: 'info' },
{ label: t('サービス'), href: '/services', icon: 'briefcase' },
{ label: t('お問い合わせ'), href: '/contact', icon: 'mail' }
];
return (
<nav>
{menuItems.map((item) => (
<a key={item.href} href={item.href} title={item.label}>
<Icon name={item.icon} />
{item.label}
</a>
))}
</nav>
);
}ダイナミックコンテンツファクトリ
// utils/productData.js
export function getProductMessages(t) {
return {
categories: [
{ id: 'electronics', name: t('電化製品') },
{ id: 'clothing', name: t('衣料品') },
{ id: 'books', name: t('書籍') }
],
statusMessages: {
available: t('在庫あり・発送可能'),
backordered: t('取り寄せ中・2〜3週間で発送'),
discontinued: t('この商品は販売終了しました')
},
errors: {
notFound: t('商品が見つかりません'),
outOfStock: t('申し訳ございません。この商品は現在在庫切れです')
}
};
}
// components/ProductCard.jsx
import { useGT } from 'gt-next';
import { getProductMessages } from '../utils/productData';
function ProductCard({ product }) {
const t = useGT();
const messages = getProductMessages(t);
return (
<div>
<h3>{product.name}</h3>
<p>{messages.statusMessages[product.status]}</p>
<span>{messages.categories.find(c => c.id === product.categoryId)?.name}</span>
</div>
);
}メタデータを扱う Server Component
import { getGT } from 'gt-next/server';
export async function generateMetadata({ params }) {
const t = await getGT();
return {
title: t('製品カタログ — 必要なものが見つかります'),
description: t('高品質な製品を豊富なラインアップからご覧いただけます'),
openGraph: {
title: t('製品をショッピング'),
description: t('高評価アイテムのお得な情報を見つけよう'),
}
};
}
export default async function ProductPage() {
const t = await getGT();
return (
<div>
<h1>{t('注目の製品')}</h1>
<p>{t('最新・人気のアイテムをご覧ください')}</p>
</div>
);
}よくある問題点
実行時の動的コンテンツ
文字列はビルド時に確定している必要があり、動的コンテンツは翻訳できません。
// ❌ 動的な内容は動作しません
function MyComponent() {
const [userMessage, setUserMessage] = useState('');
const t = useGT();
return <p>{t(userMessage)}</p>; // これは失敗します
}
// ✅ あらかじめ定義した文字列を使う
function MyComponent() {
const [messageType, setMessageType] = useState('welcome');
const t = useGT();
const messages = {
welcome: t('アプリへようこそ!'),
goodbye: t('ご利用ありがとうございます!')
};
return <p>{messages[messageType]}</p>;
}Hook のルール違反
useGT を使用する場合は、React のフックのルールに従ってください。
// ❌ フックを条件分岐の中で呼び出さないでください
function MyComponent({ showMessage }) {
if (showMessage) {
const t = useGT(); // フックのルール違反
return <p>{t('こんにちは!')}</p>;
}
return null;
}
// ✅ フックは必ずトップレベルで呼び出してください
function MyComponent({ showMessage }) {
const t = useGT();
if (showMessage) {
return <p>{t('こんにちは!')}</p>;
}
return null;
}同期処理と非同期処理の取り違え
コンポーネントの種類に合った適切な関数を使ってください。
// ❌ 誤り: 非同期コンポーネントで useGT を使用している
export default async function AsyncComponent() {
const t = useGT(); // これは動作しません
return <p>{t('Hello')}</p>;
}
// ✅ 正しい: 非同期コンポーネントで getGT を使用する
export default async function AsyncComponent() {
const t = await getGT();
return <p>{t('Hello')}</p>;
}
// ✅ 正しい: 同期コンポーネントで useGT を使用する
export default function SyncComponent() {
const t = useGT();
return <p>{t('Hello')}</p>;
}実行時に翻訳が必要な真に動的なコンテンツについては、Dynamic Content Guideをご覧ください。
次のステップ
- Dynamic Content ガイド - 実行時の翻訳を扱う
- Shared Strings ガイド - 再利用可能な翻訳を整理する
- APIリファレンス:
このガイドはいかがですか?