Getting Started Internationalizing (i18n) with Intlayer and Next.js using Page Router

    What is Intlayer?

    Intlayerは、現代のWebアプリケーションにおける多言語サポートを簡素化するために設計された革新的なオープンソースの国際化(i18n)ライブラリです。Intlayerは、最新のNext.jsフレームワーク、特にその従来のPage Routerとシームレスに統合されます。

    Intlayerを使用することで、以下が可能になります:

    • 宣言型辞書を使用して翻訳を簡単に管理できます。
    • メタデータ、ルート、およびコンテンツを動的にローカライズできます。
    • 自動生成された型によりTypeScriptサポートを保証し、オートコンプリートとエラー検出を向上させます。
    • 動的ロケール検出や切り替えなどの高度な機能から恩恵を受けられます。

    IntlayerはNext.js 12、13、14、および15に対応しています。Next.js App Routerを使用している場合は、App Router ガイドを参照してください。Next.js 15については、こちらのガイドを参照してください。


    Step-by-Step Guide to Set Up Intlayer in a Next.js Application Using Page Router

    Step 1: Install Dependencies

    必要なパッケージをお好みのパッケージマネージャーを使用してインストールします:

    bash
    npm install intlayer next-intlayer
    • intlayer

      設定管理、翻訳、コンテンツ宣言、トランスパイレーション、CLIコマンドのための国際化ツールを提供するコアパッケージです。

    • next-intlayer

      IntlayerとNext.jsを統合するパッケージです。Next.jsの国際化のためのコンテキストプロバイダとフックを提供します。さらに、WebpackまたはTurbopackとの統合のためのNext.jsプラグイン、ユーザーの優先ロケールの検出、クッキーの管理、URLリダイレクトの処理のためのミドルウェアが含まれています。

    Step 2: Configure Your Project

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

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [      Locales.ENGLISH,      Locales.FRENCH,      Locales.SPANISH,      // 他のロケールをここに追加    ],    defaultLocale: Locales.ENGLISH,  },};export default config;

    この設定ファイルを通じて、ローカライズされたURL、ミドルウェアのリダイレクト、クッキーの名前、コンテンツ宣言の場所と拡張子を設定し、Intlayerのログをコンソールに表示しないようにすることができます。利用可能なパラメーターの完全なリストについては、設定のドキュメントを参照してください。

    Step 3: Integrate Intlayer with Next.js Configuration

    Next.jsの設定を変更してIntlayerを統合します:

    next.config.mjs
    import { withIntlayer } from "next-intlayer/server";/** @type {import('next').NextConfig} */const nextConfig = {  // 既存のNext.js設定};export default withIntlayer(nextConfig);

    withIntlayer() Next.jsプラグインは、IntlayerをNext.jsに統合するために使用されます。これは、コンテンツ宣言ファイルの構築を確実にし、開発モードでそれらを監視します。これは、WebpackまたはTurbopack環境内でIntlayerの環境変数を定義します。また、パフォーマンスを最適化するためのエイリアスを提供し、サーバーコンポーネントとの互換性を保証します。

    Step 4: Configure Middleware for Locale Detection

    ユーザーの優先ロケールを自動的に検出し処理するためのミドルウェアを設定します:

    src/middleware.ts
    export { intlayerMiddleware as middleware } from "next-intlayer/middleware";export const config = {  matcher:    "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",};

    matcherパラメーターは、アプリケーションのルートに一致するように調整します。詳細については、Next.jsのマッチャーの設定に関するドキュメントを参照してください。

    Step 5: Define Dynamic Locale Routes

    ユーザーのロケールに基づいてローカライズされたコンテンツを配信するために、動的ルーティングを実装します。

    1. ロケール固有のページを作成:

      メインページファイルの名前を[locale]の動的セグメントを含むように変更します。

      bash
      mv src/pages/index.tsx src/pages/[locale]/index.tsx
    2. _app.tsxを更新してローカライズを処理:

      Intlayerプロバイダを含めるように_app.tsxを修正します。

      src/pages/_app.tsx
      import type { FC } from "react";import type { AppProps } from "next/app";import { IntlayerClientProvider } from "next-intlayer";const App: FC<AppProps> = ({ Component, pageProps }) => {  const { locale } = pageProps;  return (    <IntlayerClientProvider locale={locale}>      <Component {...pageProps} />    </IntlayerClientProvider>  );};export default App;
    3. getStaticPathsgetStaticPropsを設定:

      [locale]/index.tsxで、異なるロケールを処理するためのパスとプロパティを定義します。

      src/pages/[locale]/index.tsx
      import type { FC } from "react";import type { GetStaticPaths, GetStaticProps } from "next";import { type Locales, getConfiguration } from "intlayer";const HomePage: FC = () => <div>{/* ここにあなたのコンテンツ */}</div>;export const getStaticPaths: GetStaticPaths = () => {  const { internationalization } = getConfiguration();  const { locales } = internationalization;  const paths = locales.map((locale) => ({    params: { locale },  }));  return { paths, fallback: false };};export const getStaticProps: GetStaticProps = ({ params }) => {  const locale = params?.locale as string;  return {    props: {      locale,    },  };};export default HomePage;

    getStaticPathsgetStaticPropsは、Next.js Page Routerにおいて、アプリケーションがすべてのロケールに必要なページを事前に生成することを保証します。このアプローチはランタイムの計算を減らし、ユーザー体験を向上させます。詳細については、Next.jsのgetStaticPathsgetStaticPropsに関するドキュメントを参照してください。

    Step 6: Declare Your Content

    翻訳を保存するためのコンテンツ宣言を作成し管理します。

    src/pages/[locale]/home.content.ts
    import { t, type DeclarationContent } from "intlayer";const homeContent = {  key: "home",  content: {    title: t({      en: "Welcome to My Website",      fr: "Bienvenue sur mon site Web",      es: "Bienvenido a mi sitio web",    }),    description: t({      en: "Get started by editing this page.",      fr: "Commencez par éditer cette page.",      es: "Comience por editar esta página.",    }),  },} satisfies DeclarationContent;export default homeContent;

    コンテンツの宣言についての詳細は、コンテンツ宣言ガイドを参照してください。

    Step 7: Utilize Content in Your Code

    アプリケーション全体でコンテンツ辞書にアクセスして、翻訳されたコンテンツを表示します。

    src/pages/[locale]/index.tsx
    import type { FC } from "react";import { useIntlayer } from "next-intlayer";import { ComponentExample } from "@components/ComponentExample";const HomePage: FC = () => {  const content = useIntlayer("home");  return (    <div>      <h1>{content.title}</h1>      <p>{content.description}</p>      <ComponentExample />      {/* 追加のコンポーネント */}    </div>  );};// ... 残りのコード(getStaticPathsおよびgetStaticPropsを含む)export default HomePage;
    src/components/ComponentExample.tsx
    import type { FC } from "react";import { useIntlayer } from "next-intlayer";export const ComponentExample: FC = () => {  const content = useIntlayer("component-example"); // 対応するコンテンツ宣言を持っていることを確認する  return (    <div>      <h2>{content.title}</h2>      <p>{content.content}</p>    </div>  );};

    string属性(例:alttitlehrefaria-label)で翻訳を使用する場合は、以下のように関数の値を呼び出してください:

    jsx
    <img src={content.image.src.value} alt={content.image.value} />

    useIntlayerフックについての詳細はドキュメントを参照してください。

    (Optional) Step 8: Internationalize Your Metadata

    ページのタイトルや説明などのメタデータを国際化するには、getStaticProps関数とIntlayerのgetTranslationContent関数を組み合わせて使用します。

    src/pages/[locale]/index.tsx
    import { GetStaticPaths, GetStaticProps } from "next";import { type IConfigLocales, getTranslationContent, Locales } from "intlayer";import { useIntlayer } from "next-intlayer";interface HomePageProps {  locale: string;  metadata: Metadata;}const HomePage = ({ metadata }: HomePageProps) => {  // メタデータは、必要に応じてheadや他のコンポーネントで使用できます  return (    <div>      <Head>        <title>{metadata.title}</title>        <meta name="description" content={metadata.description} />      </Head>      {/* 追加のコンテンツ */}    </div>  );};export const getStaticProps: GetStaticProps = async ({ params }) => {  const locale = params?.locale as string;  const t = <T,>(content: IConfigLocales<T>) =>    getTranslationContent(content, locale);  const metadata = {    title: t({      en: "My Website",      fr: "Mon Site Web",      es: "Mi Sitio Web",    }),    description: t({      en: "Welcome to my website.",      fr: "Bienvenue sur mon site Web.",      es: "Bienvenido a mi sitio web.",    }),  };  return {    props: {      locale,      metadata,    },  };};export default HomePage;// ... 残りのコード(getStaticPathsを含む)

    (Optional) Step 9: Change the Language of Your Content

    ユーザーが言語を動的に切り替えられるように、useLocaleフックによって提供されるsetLocale関数を使用します。

    src/components/LanguageSwitcher.tsx
    import {  Locales,  getHTMLTextDir,  getLocaleName,  getLocalizedUrl,} from "intlayer";import { useLocalePageRouter } from "next-intlayer";import { type FC } from "react";const LocaleSwitcher: FC = () => {  const { locale, pathWithoutLocale, availableLocales, setLocale } =    useLocalePageRouter();  return (    <ol>      {availableLocales.map((localeItem) => (        <li key={localeItem}>          <a            href={getLocalizedUrl(pathWithoutLocale, localeItem)}            hrefLang={localeItem}            aria-current={locale === localeItem ? "page" : undefined}            onClick={(e) => {              e.preventDefault();              setLocale(localeItem);            }}          >            <span>              {/* 自国語での言語 - 例:Français */}              {getLocaleName(localeItem, locale)}            </span>            <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>              {/* 現在のロケールでの言語 - 例:Francés */}              {getLocaleName(localeItem)}            </span>            <span dir="ltr" lang={Locales.ENGLISH}>              {/* 英語での言語 - 例:French */}              {getLocaleName(localeItem, Locales.ENGLISH)}            </span>            <span>              {/* 自国語での言語 - 例:FR */}              {localeItem}            </span>          </a>        </li>      ))}    </ol>  );};

    useLocalePageRouter APIはuseLocaleと同じです。useLocaleフックについての詳細は、ドキュメントを参照してください。

    ドキュメントリファレンス:

    1. TypeScriptの利点の例:

      オートコンプリートの例

      翻訳エラーの例

    Git Configuration

    リポジトリをきれいに保ち、生成されたファイルをコミットしないようにするために、Intlayerによって作成されたファイルを無視することをお勧めします。

    次の行を.gitignoreファイルに追加します:

    .gitignore
    # Intlayerによって生成されたファイルを無視します.intlayer

    Additional Resources

    このガイドに従うことで、Next.jsアプリケーションにIntlayerを効果的に統合し、Webプロジェクトのために強力でスケーラブルな国際化サポートを有効にすることができます。

    このドキュメントを改善するアイデアがある場合は、GitHubでプルリクエストを送信することで自由に貢献してください。

    ドキュメントへのGitHubリンク