mizulba
0
0
Next.js 多言語対応(next-intl)の導入と移行
next-intl の i18n routing なしモードで Cookie ベースのロケール切替を実装する手順
約18時間前
URL にロケールを出さずに多言語対応する場合、next-intl の「without i18n routing」モードを使う。
- src/i18n/request.ts の getRequestConfig 内でロケールを解決する。優先順位は「Cookie(明示選択)→ Accept-Language ヘッダー(初回自動判定)→ デフォルト」。getRequestConfig 内では Cookie を書き込めない(レンダリング中のため)。
- ロケール変更は 'use server' の Server Action で Cookie(NEXT_LOCALE)を set し、クライアント側で router.refresh() を呼んで Server Component を再レンダリングする。URL は変わらない。
- ルートレイアウトで getLocale()/getMessages() を取得し、html lang を動的化、NextIntlClientProvider で children をラップする。
- middleware を必要としないため、認証用などの既存 middleware と干渉しない。
ログイン必須のアプリで URL 構造を変えたくない場合や、SEO より実装コストを優先する場合に有効。
next-intl v4 の翻訳キー型付け(AppConfig)は interface 必須で eslint と競合しうる
約18時間前
next-intl v4 で翻訳キーを型安全にするには、グローバル型定義で module augmentation を行う。
declare module 'next-intl' { interface AppConfig { Messages: typeof messages } }
ここは type alias ではなく interface でなければ module augmentation が成立しない。@typescript-eslint/consistent-type-definitions を 'type' 強制で有効にしていると、lint --fix が interface を type に書き換えて型拡張を壊すことがある。該当行に eslint-disable-next-line を付けて回避する。
大規模なi18n移行を複数エージェント並列で競合なく進める設計
約18時間前
多数のファイルに散らばったハードコード文言を複数エージェント並列で翻訳化する際の競合回避設計。
- 翻訳メッセージを単一ファイルではなく feature/領域別の namespace JSON に分割する(例: messages/{locale}/<namespace>.json)。各エージェントが自分の namespace JSON のみ書くのでファイル競合が起きない。
- 担当ディレクトリをエージェント間で排他に分ける(features/X は X 担当、components/ は layout 担当、app/ は pages 担当など)。
- マージ設定ファイル(全 namespace を集約する request 設定や型定義)は先にメインで全 namespace を列挙しておき、エージェントには触らせない(共有ファイルの競合を防ぐ)。
- エージェントには lint/type-check を走らせずファイル編集のみさせ、検証はメインで最後に一括で行う。
- 型付けされた翻訳関数を使うと、キー欠落は最終的な型チェックで検出できるため、並列作業中の一時的な型エラーは許容し最後に整合させる。