Intlayerの今後のリリースに関する通知を受け取る
    作成:2026-01-10最終更新:2026-01-10

    Next.js 16 ウェブサイトを翻訳する(ページパスに [locale] を含めない) — Intlayer を使った国際化 (i18n)

    GitHub の アプリケーションテンプレート を参照してください。

    目次

    Intlayer とは?

    Intlayer は、現代のウェブアプリケーションにおける多言語対応を簡素化するために設計された、革新的なオープンソースの国際化(i18n)ライブラリです。Intlayer は、強力な App Router を含む最新の Next.js 16 フレームワークとシームレスに統合されます。効率的なレンダリングのために Server Components を活用するよう最適化されており、Turbopack と完全に互換性があります。

    Intlayer を使うと、以下が可能になります:

    • コンポーネントレベルで宣言的な辞書を使い、翻訳を簡単に管理できます。
    • メタデータ、ルート、コンテンツを動的にローカライズできます。
    • クライアント側およびサーバー側のコンポーネントの両方で翻訳にアクセスできます。
    • 自動生成された型による TypeScript サポートを確保し、オートコンプリートとエラー検出を向上させます。
    • 高度な機能を活用できます(動的なロケール検出や切り替えなど)。
    Intlayer は Next.js 12、13、14、16 と互換性があります。Next.js の Page Router を使用している場合はこの ガイド を参照してください。App Router を使用している Next.js 12、13、14 に関しては、この ガイド を参照してください。

    Next.js アプリケーションで Intlayer をセットアップする手順

    ステップ 1: 依存関係をインストール

    npm を使用して必要なパッケージをインストールします:

    bash
    npm install intlayer next-intlayernpx intlayer init
    • intlayer

      国際化(internationalization)向けのコアパッケージで、設定管理、翻訳、コンテンツ宣言、transpilation、そして[CLIコマンド](/ja/doc/concept/cli)用のツールを提供します。

    • next-intlayer

    IntlayerをNext.jsと統合するパッケージです。Next.js向けの国際化のためのコンテキストプロバイダーとフックを提供します。さらに、WebpackTurbopackとIntlayerを統合するためのNext.jsプラグイン、およびユーザーの優先ロケールの検出、クッキー管理、URLリダイレクト処理のためのプロキシも含まれます。

    ステップ 2: プロジェクトを設定する

    以下が作成する最終的な構成です:

    .├── src│   ├── app│   │   ├── layout.tsx│   │   ├── page.content.ts│   │   └── page.tsx│   ├── components│   │   ├── clientComponentExample│   │   │   ├── client-component-example.content.ts│   │   │   └── ClientComponentExample.tsx│   │   ├── localeSwitcher│   │   │   ├── localeSwitcher.content.ts│   │   │   └── LocaleSwitcher.tsx│   │   └── serverComponentExample│   │       ├── server-component-example.content.ts│   │       └── ServerComponentExample.tsx│   └── proxy.ts├── intlayer.config.ts├── next.config.ts├── package.json└── tsconfig.json
    ロケールルーティングを使用したくない場合、intlayerは単純なプロバイダー/フックとして使用できます。詳細はこのガイドを参照してください。

    アプリケーションの言語を設定するための設定ファイルを作成します:

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [      Locales.ENGLISH,      Locales.FRENCH,      Locales.SPANISH,      // 他のロケール    ],    defaultLocale: Locales.ENGLISH,  },  routing: {    mode: "search-params", // または `no-prefix` - ミドルウェア検出に便利  },};export default config;
    この設定ファイルを使って、ローカライズされた URL、プロキシリダイレクト、クッキー名、コンテンツ宣言の場所と拡張子、コンソール上の Intlayer ログの無効化などを設定できます。利用可能なパラメータの完全な一覧は、設定ドキュメント を参照してください。

    ステップ 3: Next.js の設定に Intlayer を統合する

    Intlayer を使用するよう Next.js の設定を構成します:

    next.config.ts
    import type { NextConfig } from "next";import { withIntlayer } from "next-intlayer/server";const nextConfig: NextConfig = {  /* ここに設定オプションを記述 */};export default withIntlayer(nextConfig);
    withIntlayer() の Next.js プラグインは Intlayer を Next.js に統合するために使用されます。コンテンツ宣言ファイルの生成を行い、開発モードでそれらを監視します。Webpack または Turbopack 環境内で Intlayer の環境変数を定義します。さらに、パフォーマンス最適化のためのエイリアスを提供し、サーバーコンポーネントとの互換性を確保します。

    withIntlayer() 関数は Promise 関数です。ビルド開始前に Intlayer の辞書を準備することを可能にします。他のプラグインと一緒に使用する場合は、await できます。例:

    const nextConfig = await withIntlayer(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;

    同期的に使用したい場合は、withIntlayerSync() 関数を使用できます。例:

    const nextConfig = withIntlayerSync(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;

    Intlayer は、コマンドラインフラグ(--webpack--turbo、または --turbopack)や現在の Next.js のバージョンに基づいて、プロジェクトが webpack または Turbopack のどちらを使用しているかを自動的に検出します。

    next>=16 以降、Rspack を使用している場合は、Turbopack を無効化して Intlayer に webpack 設定を明示的に使用させる必要があります:

    withRspack(withIntlayer(nextConfig, { enableTurbopack: false }));

    ステップ 4: 動的ロケールルートを定義する

    RootLayout の中身をすべて削除し、次のコードに置き換えてください:

    src/app/layout.tsx
    import type { Metadata } from "next";import type { ReactNode } from "react";import "./globals.css";import { IntlayerClientProvider, LocalPromiseParams } from "next-intlayer";import { getHTMLTextDir, getIntlayer } from "intlayer";import { getLocale } from "next-intlayer/server";export { generateStaticParams } from "next-intlayer";export const generateMetadata = async ({  params,}: LocalPromiseParams): Promise<Metadata> => {  const { locale } = await params;  const { title, description, keywords } = getIntlayer("metadata", locale);  return {    title,    description,    keywords,  };};const RootLayout = async ({  children,}: Readonly<{  children: ReactNode;}>) => {  const locale = await getLocale();  return (    <html lang={locale} dir={getHTMLTextDir(locale)}>      <IntlayerClientProvider defaultLocale={locale}>        <body>{children}</body>      </IntlayerClientProvider>    </html>  );};export default RootLayout;
    src/app/metadata.content.mjs
    import { t, type Dictionary } from "intlayer";/** @type {import('intlayer').Dictionary<import('next').Metadata>} */const metadataContent = {  key: "metadata",  content: {    title: t({      ja: "ワークフローを合理化する私のプロジェクトのタイトル",      en: "My Project Title",      fr: "Le Titre de mon Projet",      es: "El Título de mi Proyecto",    }),    description: t({      ja: "ワークフローを効率化し、生産性を向上させるために設計された革新的なプラットフォームをご紹介します。",      en: "Discover our innovative platform designed to streamline your workflow and boost productivity.",      fr: "Découvrez notre plateforme innovante conçue pour simplifier votre flux de travail et booster votre productivité.",      es: "Descubra nuestra plataforma innovadora diseñada para simplificar su flujo de trabajo y aumentar su productividad.",    }),    keywords: t({      ja: ["イノベーション", "生産性", "ワークフロー", "SaaS"],      en: ["innovation", "productivity", "workflow", "SaaS"],      fr: ["innovation", "productivité", "flux de travail", "SaaS"],      es: ["innovación", "productividad", "flujo de trabajo", "SaaS"],    }),  },};export default metadataContent;
    src/app/page.content.ts
    import { t, type Dictionary } from "intlayer";const pageContent = {  key: "page",  content: {    getStarted: {      main: t({        ja: "編集して始めましょう",        en: "Get started by editing",        fr: "Commencez par éditer",        es: "Comience por editar",      }),      pageLink: "src/app/page.tsx",    },  },} satisfies Dictionary;export default pageContent;
    コンテンツの宣言は、アプリケーション内の任意の場所に定義できます。ただし、それらが contentDir ディレクトリ(デフォルトは ./src)に含まれており、コンテンツ宣言ファイルの拡張子が一致している必要があります(デフォルト: .content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx})。
    詳細は、コンテンツ宣言のドキュメント を参照してください。

    ステップ6: コード内でコンテンツを利用する

    アプリケーション全体からコンテンツ辞書にアクセスします:

    src/app/page.tsx
    import type { FC } from "react";import { ClientComponentExample } from "@components/clientComponentExample/ClientComponentExample";import { ServerComponentExample } from "@components/serverComponentExample/ServerComponentExample";import {  IntlayerServerProvider,  useIntlayer,  getLocale,} from "next-intlayer/server";import { NextPage } from "next";import { headers, cookies } from "next/headers";const PageContent: FC = () => {  const content = useIntlayer("page");  return (    <>      <p>{content.getStarted.main}</p>      <code>{content.getStarted.pageLink}</code>    </>  );};const Page: NextPage = async () => {  // Next.js 15+ では headers と cookies を await してください  const headerList = await headers();  const cookieList = await cookies();  const locale = await getLocale({    // まず intlayer のクッキーを確認します(デフォルト: 'INTLAYER_LOCALE')    getCookie: (name) => cookieList.get(name)?.value,    // 次に intlayer ヘッダーを確認します(デフォルト: 'x-intlayer-locale')    // 最後に accept-language ヘッダーを確認します('accept-language')    getHeader: (name) => headerList.get(name),  });  return (    <IntlayerServerProvider locale={locale}>      <PageContent />      <ServerComponentExample />      <ClientComponentExample />    </IntlayerServerProvider>  );};export default Page;
    src/components/serverComponentExample/ServerComponentExample.tsx
    import type { FC } from "react";import { useIntlayer } from "next-intlayer/server";export const ServerComponentExample: FC = () => {  const content = useIntlayer("server-component-example"); // 関連コンテンツの宣言を作成  return (    <div>      <h2>{content.title}</h2>      <p>{content.content}</p>    </div>  );};
    alttitlehrefaria-label などの string 属性でコンテンツを使用する場合は、関数の値を呼び出す必要があります。例えば:
    <img src={content.image.src.value} alt={content.image.value} />
    useIntlayer フックの詳細はドキュメントを参照してください。

    (オプション)ステップ7: ロケール検出のためにプロキシを設定

    ユーザーの優先ロケールを検出するようにプロキシを設定します:

    src/proxy.ts
    export { intlayerProxy as proxy } from "next-intlayer/proxy";export const config = {  matcher:    "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",};
    intlayerProxy はユーザーの優先ロケールを検出し、設定に記載された適切な URL へリダイレクトするために使用されます。さらに、ユーザーの優先ロケールをクッキーに保存することも可能にします。
    複数のプロキシを連結する必要がある場合(例えば、認証やカスタムプロキシと intlayerProxy を組み合わせる場合)、Intlayer は multipleProxies というヘルパーを提供しています。
    import { multipleProxies, intlayerProxy } from "next-intlayer/proxy";import { customProxy } from "@utils/customProxy";export const proxy = multipleProxies([intlayerProxy, customProxy]);

    (オプション)ステップ 8: コンテンツの言語を変更する

    Next.jsでコンテンツの言語を切り替えるには、推奨される方法はLinkコンポーネントを使用してユーザーを適切なローカライズされたページにリダイレクトすることです。Linkコンポーネントはページのプリフェッチを可能にし、フルページのリロードを回避するのに役立ちます。

    src/components/localeSwitcher/LocaleSwitcher.tsx
    "use client";import type { FC } from "react";import { Locales, getHTMLTextDir, getLocaleName } from "intlayer";import { useLocale } from "next-intlayer";export const LocaleSwitcher: FC = () => {  const { locale, availableLocales, setLocale } = useLocale({    onChange: () => window.location.reload(),  });  return (    <div>      <button popoverTarget="localePopover">{getLocaleName(locale)}</button>      <div id="localePopover" popover="auto">        {availableLocales.map((localeItem) => (          <button            key={localeItem}            aria-current={locale === localeItem ? "page" : undefined}            onClick={() => setLocale(localeItem)}          >            <span>              {/* ロケール - 例: FR */}              {localeItem}            </span>            <span>              {/* 自身のロケールでの言語名 - 例: Français */}              {getLocaleName(localeItem, locale)}            </span>            <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>              {/* 現在のロケールでの言語名 - 例: 現在のロケールが Locales.SPANISH の場合: Francés */}              {getLocaleName(localeItem)}            </span>            <span dir="ltr" lang={Locales.ENGLISH}>        {availableLocales.map((localeItem) => (          <button            key={localeItem}            aria-current={locale === localeItem ? "page" : undefined}            onClick={() => setLocale(localeItem)}          >            <span>              {/* ロケール - 例: FR */}              {localeItem}            </span>            <span>              {/* 自身のロケールでの言語名 - 例: Français */}              {getLocaleName(localeItem, locale)}            </span>            <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>              {/* 現在のロケールでの言語名 - 例: 現在のロケールが Locales.SPANISH の場合: Francés */}              {getLocaleName(localeItem)}            </span>            <span dir="ltr" lang={Locales.ENGLISH}>              {/* 英語での言語名 — 例: French */}              {getLocaleName(localeItem, Locales.ENGLISH)}            </span>          </button>        ))}      </div>    </div>  );};
    代替方法として、useLocale フックが提供する setLocale 関数を使用できます。この関数はページのプリフェッチを許可しません。詳細は useLocale フックのドキュメント を参照してください。

    ドキュメント参照:

    (任意)ステップ 9: Server Actions で現在のロケールを取得する

    Server Action の内部でアクティブなロケールが必要な場合(例: メールのローカライズやロケール対応のロジックを実行する場合)、next-intlayer/server から getLocale を呼び出してください:

    src/app/actions/getLocale.ts
    "use server";import { getLocale } from "next-intlayer/server";export const myServerAction = async () => {  const locale = await getLocale();  // ロケールを使って処理を行います};

    getLocale 関数はユーザーのロケールを決定するためにカスケード戦略を採用します:

    1. まず、プロキシによって設定されている可能性のあるロケール値についてリクエストヘッダーを確認します
    2. ヘッダーにロケールが見つからない場合、クッキーに保存されたロケールを探します
    3. クッキーが見つからない場合、ブラウザ設定からユーザーの優先言語を検出しようとします
    4. 最後の手段として、アプリケーションで設定されたデフォルトロケールにフォールバックします

    これにより、利用可能なコンテキストに基づいて最も適切なロケールが選択されます。

    (任意)ステップ10:バンドルサイズを最適化する

    next-intlayer を使用すると、辞書はデフォルトで各ページのバンドルに含まれます。バンドルサイズを最適化するために、Intlayer はマクロを使用して useIntlayer の呼び出しをインテリジェントに置き換えるオプションの SWC プラグインを提供しています。これにより、辞書は実際にそれらを使用するページのバンドルにのみ含まれるようになります。

    この最適化を有効にするには、@intlayer/swc パッケージをインストールしてください。インストール後、next-intlayer は自動的にプラグインを検出して使用します:

    bash
    npm install @intlayer/swc --save-devnpx intlayer init
    注意: この最適化は Next.js 13 以降でのみ利用可能です。
    注意: SWCプラグインは Next.js 上でまだ実験的なため、このパッケージはデフォルトでインストールされません。将来的に変更される可能性があります。
    注意: オプションを importMode: 'dynamic' または importMode: 'live' に設定すると、Suspense に依存するため、useIntlayer の呼び出しを Suspense 境界でラップする必要があります。つまり、Page / Layout コンポーネントのトップレベルで useIntlayer を直接使用することはできません。

    Turbopackで辞書の変更を監視する

    Turbopackを開発サーバーとしてnext devコマンドで使用している場合、辞書の変更はデフォルトでは自動的に検出されません。

    この制限は、Turbopackがコンテンツファイルの変更を監視するためのwebpackプラグインを並列で実行できないために発生します。回避するには、intlayer watchコマンドを使用して、開発サーバーとIntlayerのビルドウォッチャーを同時に実行する必要があります。

    package.json
    {  // ... 既存の package.json 設定  "scripts": {    // ... 既存の scripts 設定    "dev": "intlayer watch --with 'next dev'",  },}
    next-intlayer@<=6.x.x を使用している場合、Next.js 16 アプリケーションを Turbopack と正しく動作させるために --turbopack フラグを維持する必要があります。この制約を回避するには next-intlayer@>=7.x.x の使用を推奨します。

    TypeScript の設定

    Intlayer は TypeScript の利点を活かすためにモジュール拡張 (module augmentation) を使用し、コードベースをより堅牢にします。

    オートコンプリート

    翻訳エラー

    TypeScript の設定に自動生成された型が含まれていることを確認してください。

    tsconfig.json
    {  // ... 既存の TypeScript 設定  "include": [    // ... 既存の TypeScript 設定    ".intlayer/**/*.ts", // 自動生成された型を含める  ],}### Git 設定Intlayer によって生成されたファイルは無視することを推奨します。これにより、これらのファイルを Git リポジトリにコミットすることを避けられます。これを行うには、次の内容を `.gitignore` ファイルに追加してください:```plaintext fileName=".gitignore"# Intlayer によって生成されたファイルを無視する.intlayer

    VS Code 拡張機能

    Intlayer の開発体験を向上させるために、公式の Intlayer VS Code Extension をインストールできます。

    VS Code Marketplace からインストール

    この拡張機能は次の機能を提供します:

    • Autocompletion: 翻訳キーの補完。
    • リアルタイムのエラーチェック: 翻訳が欠落している箇所の検出。
    • 翻訳されたコンテンツのインラインプレビュー
    • 翻訳を簡単に作成・更新するためのクイックアクション

    拡張機能の使用方法の詳細については、Intlayer VS Code 拡張機能のドキュメント を参照してください。

    さらに進む

    さらに進むには、ビジュアルエディタ を実装するか、CMS を使用してコンテンツを外部化できます。

    Intlayerの今後のリリースに関する通知を受け取る