📝

【Fire Base Studio】Next.jsの多言語化ライブラリはnext-i18next next-intlかreact-intl

に公開

結論Firebase Studio × Next.js App Routerで多言語化 next-intl

Next.js で多言語対応(i18n)を行う際、選択肢となるライブラリはいくつかあります。しかし、Firebase Studio + App Router 環境では、ほとんどのライブラリが制約を抱えており、唯一スムーズに統合できるのが next-intl です。

【Fire Base Studio】を使った上でのnext.jsについての説明ですが、多言語化というのは基本的にはURLに英語、日本語、フランス語などページを分けるようなディレクトリ構造を作るので、next.js13以降に導入されたApp Routerなどが深く関係しており、next.jsで多言語化にする際にはnext-intlを採用することになります。

多言語化でよく目にするのは、i18nという言葉ですが、これは「Internationalization(国際化)」の略語で、ソフトウェアや製品を多様な言語や文化に対応できるように設計・開発するプロセスを指します。この「18」は、最初の「I」と最後の「n」の間の文字数に由来します。

Next.jsは、ReactをベースにしたJavaScriptフレームワークですから、当然ライブラリの候補としては、react-intlも挙げられます。

しかし、冒頭で述べたように、Next.js 13以降で導入された新しいルーティング方式を使って構築されたアプリケーションで従来の pages/ ディレクトリベースの「Pages Router」ではなく、app/ ディレクトリを使うため、最適化されたNext-intlとなります。

FireBaseStudioでGeminiに多言語化を指示する場合の注意点

Firebase StudioでGeminiに多言語化を指示した場合でも、AIが誤って別のライブラリ(例:next-i18next や i18next)を提案したり、勝手にインストールする可能性はあります。これは、Geminiがプロンプトベースで動作しており、プロジェクトの構成やApp Routerの使用状況を正確に把握できない場合があるためです。


📦 i18nライブラリ比較表(App Router対応状況)

ライブラリ名 App Router対応 主な課題 備考
next-intl ✅ 完全対応 なし App Router専用設計。URLルーティング・翻訳・ミドルウェアが統合可能。
next-i18next ⚠️ 一部対応 Pages Router向け。App Routerでは設定が複雑 next.config.js に依存。URL制御が難しい。
i18next ❌ 非対応 useTranslation() が Client Component に依存 Server Componentでは使えない。
react-intl ❌ 非対応 Providerの設置が複雑。App Routerとの整合性が悪い SSRやServer Componentとの相性が悪い。

next-intl をインストールするには、以下のコマンドを使用します:

npm install next-intl@latest

または、Yarn を使っている場合は:

yarn add next-intl@latest

このコマンドで、最新バージョンの next-intl がプロジェクトに追加されます。
インストール後は、messages ディレクトリに翻訳ファイル(例:en.json, ja.json)を作成したりします。

✅ なぜ i18next ではなく、next-intl が使えるのか

Next.js の App Router では、i18next は以下の理由で非推奨または制約ありです:

useTranslation() が Client Component に依存しており、Server Componentでは使えない
URLベースの言語切り替え(例:/ja/about)を自動で制御する仕組みがない
middleware.ts による言語判定やリダイレクトが統合されていない
そのため、Next.js App Router環境では next-intl の方が構造的・再現性の高い設計が可能です。

1. next-intl はApp Routerに最適化された構造

// config.ts
import { Pathnames, LocalePrefix } from "next-intl/routing";

export const defaultLocale = "en" as const;
export const locales = ["en", "ja", "fr"] as const;

export const pathnames: Pathnames<typeof locales> = {
  "/": "/",
};

export const localePrefix = "as-needed" satisfies LocalePrefix;
  • localePrefix: "as-needed" により、デフォルト言語(例: 英語)には /en を付けず、他言語には /ja, /fr を付ける。
  • pathnames により、言語ごとのURL構造を明示的に定義可能。

2. Middleware(ミドルウェア)による言語判定とリダイレクト

// middleware.ts
import { createMiddleware } from "next-intl/middleware";
import { locales, localePrefix, defaultLocale } from "./config";

export default createMiddleware({
  defaultLocale,
  localePrefix,
  locales,
});
  • 初回アクセス時にブラウザの言語を判定し、適切なロケールにリダイレクト。
  • as-needed 設定により、URLが冗長にならず、SEOにも有利。

「middleware.ts」は自動生成されません。このファイルは、開発者が明示的に作成する必要がある設定ファイルです。

next-intl は柔軟性を重視しているため、プロジェクトごとの言語構成やURL設計に合わせて手動で設定する設計思想です。

middleware.ts は Next.js のルートレベルに配置され、リクエスト時の言語判定・リダイレクト制御を担うため、プロジェクトの要件に応じてカスタマイズが必要です。

next-intlの公式ドキュメントにテンプレートコードがあります。

https://next-intl.dev/docs/routing/middleware

上記のページにあるテンプレートは次の通りです。

import createMiddleware from 'next-intl/middleware';
import {routing} from './i18n/routing';
 
export default createMiddleware(routing);
 
export const config = {
  // Match all pathnames except for
  // - … if they start with `/api`, `/trpc`, `/_next` or `/_vercel`
  // - … the ones containing a dot (e.g. `favicon.ico`)
  matcher: '/((?!api|trpc|_next|_vercel|.*\\..*).*)'
};

ドキュメントで登場するMiddleareもシンプルで実装に至るまでも学習コストは要しません。
Routing
├── Setup // 基本的な導入手順(locales, defaultLocaleなど)
├── Configuration // pathnamesやlocalePrefixの設定
├── Middleware // 言語判定とリダイレクト処理
└── Navigation // 言語切替リンクやナビゲーション制御
この構成により、国際化に必要な要素が分離されていて、再現性の高い設計が可能です。

実装例

// middleware.ts
import { createMiddleware } from 'next-intl/middleware';
import { locales, defaultLocale, localePrefix } from './config';

export default createMiddleware({
  locales,
  defaultLocale,
  localePrefix,
});

これだけで、以下のような挙動が自動的に処理されます:

/ にアクセスしたとき、ブラウザの言語が ja なら /ja にリダイレクト

localePrefix: "as-needed" に従って、デフォルト言語には /en を付けない

言語ごとのURL構造が明示的に制御される


3.Next-intl ディレクトリ構造、middleware.tsのファイルを置く場所

ディレクトリ構成がシンプル

├── app/
│   └── [locale]/
│       ├── page.tsx
│       └── layout.tsx
├── messages/
│   ├── en.json
│   ├── ja.json
│   └── fr.json
├── config.ts
├── middleware.ts
  • [locale] ディレクトリにより、言語ごとのページを自動的に切り替え。
  • messages/*.json に翻訳文を格納し、getRequestConfig() でロード。

next-intl はミドルウェアなしでも使えるが…

next-intl はミドルウェアなしでも使えます。ただし、ミドルウェアを使わない場合は「言語ごとのURL制御」や「自動リダイレクト」などの機能が制限されるため、App Router環境で本格的な多言語対応をするならミドルウェアはほぼ必須です。

  • next-intl はミドルウェアなしでも最低限の翻訳機能は使える
  • ただし、本格的な多言語ルーティングやUX改善にはミドルウェアが必要
  • 特に localePrefix: "as-needed" を使う場合は、ミドルウェアがないと正しく動作しません

🧩 ミドルウェアなしでもできること

機能 使えるか 備考
翻訳の取得(useTranslations() ✅ 使える messages/*.json を読み込めばOK
サーバーコンポーネントでの翻訳 ✅ 使える getRequestConfig() を使えば可能
言語切替ボタン ✅ 使える createNavigation() で言語付きURLに遷移可能
自動リダイレクト(例: //ja ❌ 使えない ミドルウェアがないと判定できない
localePrefix: "as-needed" の挙動 ❌ 使えない ミドルウェアがないとURL制御できない

🔍 なぜミドルウェアが重要なのか

App Routerでは、ページの表示前に「どの言語で表示するか」を判断する必要があります。
その判定を行うのが middleware.ts です。これがないと、以下のような問題が起こります:

  • / にアクセスしても、ユーザーの言語に応じたページに自動遷移しない
  • localePrefix: "as-needed" を設定しても、URLが正しく切り替わらない
  • SEOやUXの観点で、言語ごとのURL構造が不明瞭になる

もし「ミドルウェアなしで最低限の構成を試したい」場合は、getRequestConfig()useTranslations() だけで始めることもできます。


🧠 next-intl の強みまとめ

機能 説明
✅ App Router対応 Server Componentでも翻訳が使える
✅ URLルーティング制御 pathnames による明示的なマッピング
✅ ミドルウェア統合 言語判定とリダイレクトが簡単
✅ SEO最適化 デフォルト言語に /en を付けない設計が可能
✅ 翻訳ファイルの分離 messages/*.json による明快な管理

🔚 まとめ

Firebase Studio × Next.js App Router で多言語化を行うなら、next-intl が最も合理的な選択です。
他のライブラリは App Router に対応しておらず、設定が複雑になるため、構造的・再現性の高い設計を目指すなら next-intl 一択となります。


Discussion