Next.jsで静的サイトにローカリゼーション(i18n)を設定する方法を徹底解説

Next.jsを使用して静的サイトを構築する際、多言語対応(ローカリゼーション、i18n)の実装は、グローバルなユーザー層に対応するための重要な要素です。本記事では、Next.jsが提供するi18n機能を活用し、静的サイト生成(SSG)で効率的にローカリゼーションを設定する方法を詳しく解説します。初めてi18nに取り組む方でも理解しやすいように、具体的な手順とコード例を交えて説明しますので、この記事を通じて実際のプロジェクトでの活用方法を習得してください。

目次

Next.jsのローカリゼーション(i18n)の概要


Next.jsではバージョン10以降、i18n(国際化)機能がネイティブサポートされています。この機能を活用することで、多言語対応の静的サイトやサーバーサイドレンダリング(SSR)サイトを効率的に構築できます。

i18nの特徴


Next.jsのi18n機能には以下の特徴があります:

1. 言語ごとのルーティング


URLパスに基づいて、言語ごとに異なるコンテンツを提供できます。たとえば、/enは英語、/jaは日本語のページに対応します。

2. 静的ファイルの言語別生成


静的サイト生成(SSG)を活用すると、各言語に対応したHTMLファイルをビルド時に自動生成します。

3. フルカスタマイズが可能


デフォルトの設定だけでなく、言語ファイルやカスタムロジックを自由に追加してニーズに合ったローカリゼーションが実現できます。

i18nを活用する利点

  • ユーザー体験の向上:訪問者が慣れ親しんだ言語でコンテンツを閲覧可能になります。
  • SEO強化:言語別に最適化されたページが検索エンジンで評価されやすくなります。
  • 効率的な開発:Next.jsのi18n機能を活用することで、手動でルーティングや言語切り替えを実装する手間を大幅に削減できます。

Next.jsのi18nは、グローバル展開を目指すウェブサイトにとって強力なツールです。このセクションで得た基本知識を基に、次のステップで実際の設定方法に進みます。

プロジェクトのセットアップ


Next.jsでローカリゼーション(i18n)を設定するためには、まずプロジェクトの基本構築を行います。このセクションでは、必要なツールやパッケージをインストールし、プロジェクト環境を整える手順を解説します。

1. Next.jsプロジェクトの作成


以下のコマンドを使用して、新しいNext.jsプロジェクトを作成します:

npx create-next-app@latest my-next-i18n-app
cd my-next-i18n-app

コマンドの説明

  • create-next-appは、Next.jsの公式CLIツールで、必要なディレクトリやファイルを自動生成します。
  • my-next-i18n-appはプロジェクトのディレクトリ名です。任意の名前に変更できます。

2. 必要なパッケージのインストール


ローカリゼーションの設定に必要なパッケージをインストールします。例えば、翻訳ファイル管理のためにnext-i18nexti18nextなどのライブラリを利用する場合があります。以下はその例です:

npm install next-i18next react-i18next i18next

インストールするパッケージ

  • next-i18next:Next.jsに特化したi18nライブラリ。
  • react-i18next:Reactコンポーネントでi18nを簡単に使用するためのツール。
  • i18next:翻訳ファイルを管理するための主要ライブラリ。

3. プロジェクト構造の確認


セットアップ後、プロジェクトのフォルダ構造が以下のようになっていることを確認してください:

my-next-i18n-app/
├── public/
├── src/
│   ├── pages/
│   ├── components/
│   ├── locales/   # 言語ファイルを配置するフォルダを追加
│   │   ├── en/
│   │   ├── ja/
├── next.config.js
├── package.json

4. 言語ファイルフォルダの作成


ローカリゼーションに必要な翻訳ファイルを格納するため、localesディレクトリを作成します。このフォルダ内に各言語用のサブディレクトリ(例:enja)を追加します。

プロジェクトのセットアップが完了したら、次のステップでi18n設定を実際に構築していきます。

i18n設定の基礎


Next.jsでは、next.config.jsファイルを使用してローカリゼーション(i18n)を簡単に設定できます。このセクションでは、基本的な設定手順を説明します。

1. `next.config.js`ファイルを編集


Next.jsのi18n機能は、next.config.jsに設定を記述することで有効化できます。以下は基本的な設定例です:

module.exports = {
  i18n: {
    locales: ['en', 'ja'], // 対応する言語コード
    defaultLocale: 'en',  // デフォルトの言語
  },
};

コードの説明

  • locales:対応する言語の配列を指定します。ここでは英語(en)と日本語(ja)を定義しています。
  • defaultLocale:訪問者が明示的に言語を指定しない場合に適用される言語です。

2. 言語ごとのルーティング


設定後、Next.jsは自動的に言語ごとのルートを生成します。たとえば、以下のようなURL構造が可能です:

  • /en/about(英語のaboutページ)
  • /ja/about(日本語のaboutページ)

デフォルト言語(この例ではen)の場合は、URLから言語コードを省略できます。

3. 翻訳データの準備


Next.jsは翻訳データを直接管理しませんが、外部ライブラリ(例:i18next)を利用することで動的に翻訳を提供できます。以下に翻訳データの例を示します:

ファイル構成例

locales/
├── en/
│   └── common.json
├── ja/
    └── common.json

common.jsonファイルの例(英語)

{
  "welcome": "Welcome to our site!",
  "about": "About us"
}

common.jsonファイルの例(日本語)

{
  "welcome": "私たちのサイトへようこそ!",
  "about": "私たちについて"
}

4. i18n設定の確認


Next.jsを再起動し、正しい言語ルートと翻訳が適用されているか確認します。URLパスに応じて言語が適切に切り替わることをテストしてください。

これで、Next.jsでのi18nの基本設定が完了しました。次のステップでは、具体的にページコンポーネントにローカリゼーションを適用する方法を説明します。

言語ファイルの作成と管理


ローカリゼーション(i18n)を活用するには、言語ファイルを適切に作成し管理する必要があります。このセクションでは、翻訳データを格納するJSONファイルの作成方法と運用のベストプラクティスについて解説します。

1. 翻訳データのフォルダ構成


言語ファイルは、Next.jsプロジェクト内にlocalesディレクトリを作成して管理します。以下のようなフォルダ構成を推奨します:

locales/
├── en/
│   └── common.json
├── ja/
    └── common.json

各フォルダとファイルの役割

  • locales/:すべての翻訳データを格納するルートフォルダ。
  • 言語コードのサブフォルダ(例:enja:各言語ごとの翻訳データを保存。
  • JSONファイル(例:common.json:翻訳キーと対応するテキストを定義するファイル。

2. JSONファイルの記述例


JSONファイルでは、翻訳キーとそれに対応する言語テキストをペアで定義します。

英語版(en/common.json

{
  "welcome": "Welcome to our website!",
  "about": "Learn more about us",
  "contact": "Contact us"
}

日本語版(ja/common.json

{
  "welcome": "私たちのウェブサイトへようこそ!",
  "about": "私たちについて詳しく知る",
  "contact": "お問い合わせ"
}

3. 言語ファイルの管理のコツ

  • 翻訳キーの命名規則を統一:翻訳キーは簡潔で直感的な名前をつけます(例:welcomecontact)。
  • 再利用可能性を考慮:汎用的なメッセージ(例:「次へ」、「キャンセル」など)は、common.jsonにまとめます。
  • レビューとバージョン管理:翻訳ファイルをGitで管理し、更新時には必ずレビューを実施します。

4. 翻訳ファイルを大規模に運用する方法


プロジェクトが拡大すると、翻訳ファイルが増加する可能性があります。その場合は、以下のような工夫を取り入れると効果的です:

1. セクションごとの分割


ページや機能ごとに翻訳ファイルを分割します:

locales/
├── en/
│   ├── common.json
│   ├── home.json
│   └── about.json
├── ja/
    ├── common.json
    ├── home.json
    └── about.json

2. 外部翻訳管理ツールの導入


大規模プロジェクトでは、PhraseやLokaliseなどの翻訳管理ツールを利用して効率化を図ることも有効です。

言語ファイルが適切に作成・管理できたら、次のステップでは、これらの翻訳データを実際にページコンポーネントで活用する方法を学びます。

ページでのローカリゼーションの適用


Next.jsのページコンポーネントにローカリゼーション(i18n)を適用することで、翻訳データを使って多言語対応のコンテンツを動的に表示できます。このセクションでは、react-i18nextを使用して、ページに翻訳を適用する具体的な方法を解説します。

1. `i18next`の初期化


まず、i18nextreact-i18nextを初期化する設定を行います。以下は基本的な初期化スクリプトの例です:

src/i18n.js

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import en from './locales/en/common.json';
import ja from './locales/ja/common.json';

i18n.use(initReactI18next).init({
  resources: {
    en: { translation: en },
    ja: { translation: ja },
  },
  lng: 'en', // デフォルト言語
  fallbackLng: 'en', // 言語が見つからない場合のフォールバック言語
  interpolation: {
    escapeValue: false, // Reactではエスケープは不要
  },
});

export default i18n;

2. `i18next`のプロバイダーを設定


アプリ全体で翻訳データを利用可能にするため、_app.jsI18nextProviderを設定します。

src/pages/_app.js

import '../styles/globals.css';
import { I18nextProvider } from 'react-i18next';
import i18n from '../i18n';

function MyApp({ Component, pageProps }) {
  return (
    <I18nextProvider i18n={i18n}>
      <Component {...pageProps} />
    </I18nextProvider>
  );
}

export default MyApp;

3. ページコンポーネントでの使用


各ページでuseTranslationフックを使用し、翻訳データを取得して表示します。

例:src/pages/index.js

import { useTranslation } from 'react-i18next';

export default function Home() {
  const { t } = useTranslation();

  return (
    <div>
      <h1>{t('welcome')}</h1>
      <p>{t('about')}</p>
      <p>{t('contact')}</p>
    </div>
  );
}

4. 言語切り替え機能の追加


ユーザーが言語を切り替えられるよう、ボタンやドロップダウンを設置します。

例:言語切り替えボタン

import { useTranslation } from 'react-i18next';

export default function LanguageSwitcher() {
  const { i18n } = useTranslation();

  const changeLanguage = (lng) => {
    i18n.changeLanguage(lng);
  };

  return (
    <div>
      <button onClick={() => changeLanguage('en')}>English</button>
      <button onClick={() => changeLanguage('ja')}>日本語</button>
    </div>
  );
}

5. ページへの言語切り替え機能の統合


作成した言語切り替えコンポーネントをページに統合します:

import Home from './index';
import LanguageSwitcher from './LanguageSwitcher';

export default function App() {
  return (
    <div>
      <LanguageSwitcher />
      <Home />
    </div>
  );
}

6. 動作確認


ローカルサーバーを起動し、言語が切り替わりながら正しく表示されることを確認します:

npm run dev

これで、ページにローカリゼーションを適用する方法が完了です。次のセクションでは、動的ルーティングとの連携方法について解説します。

動的ルーティングとi18nの連携


Next.jsでは動的ルーティングを利用して、i18n対応の多言語ページを効率的に管理できます。このセクションでは、言語ごとのルートを動的に生成し、i18nと連携させる方法を解説します。

1. 動的ルーティングの基礎


Next.jsの動的ルーティングを使用すると、ページを動的に生成できます。例えば、以下のように言語コードをURLに含めることが可能です:

/en/about
/ja/about

ディレクトリ構成
以下のように、動的セグメントを持つファイル名でページを作成します:

src/
├── pages/
│   ├── [locale]/
│   │   └── about.js

2. 動的ルーティングでi18nを適用


言語コードに基づいて動的にコンテンツを切り替える設定を行います。

src/pages/[locale]/about.js

import { useRouter } from 'next/router';
import { useTranslation } from 'react-i18next';

export default function About() {
  const { query } = useRouter(); // URLのlocaleを取得
  const { t, i18n } = useTranslation();

  // URLのlocaleに基づいて言語を変更
  if (query.locale) {
    i18n.changeLanguage(query.locale);
  }

  return (
    <div>
      <h1>{t('about')}</h1>
      <p>{t('welcome')}</p>
    </div>
  );
}

コードのポイント

  • useRouternext/routerを使用して、URLからlocaleを取得します。
  • i18n.changeLanguage:URLに基づいて現在の言語を変更します。

3. 言語別の静的ページを生成


Next.jsのgetStaticPathsを利用して、言語別のページを静的に生成します。

src/pages/[locale]/about.js

export async function getStaticPaths() {
  return {
    paths: [
      { params: { locale: 'en' } },
      { params: { locale: 'ja' } },
    ],
    fallback: false, // 定義されていないパスは404を返す
  };
}

export async function getStaticProps({ params }) {
  return {
    props: {
      locale: params.locale,
    },
  };
}

コードのポイント

  • getStaticPathslocaleごとのパスを事前に生成します。
  • getStaticProps:ページにlocaleを渡し、言語に応じたコンテンツを動的に提供します。

4. 言語切り替えリンクの追加


ユーザーが簡単に言語を切り替えられるよう、言語変更リンクをページに追加します。

例:言語切り替えリンク

import Link from 'next/link';

export default function LanguageSwitcher({ currentLocale }) {
  return (
    <div>
      <Link href="/en/about" locale="en">
        <a style={{ marginRight: '10px' }}>English</a>
      </Link>
      <Link href="/ja/about" locale="ja">
        <a>日本語</a>
      </Link>
    </div>
  );
}

5. 動作確認


npm run buildで静的ページを生成し、npm startでサーバーを起動して、URLに応じた言語ページが正しく表示されることを確認します。

これで動的ルーティングとi18nの連携が完了しました。次のセクションでは、静的サイト生成(SSG)とi18nの活用方法を解説します。

静的サイト生成(SSG)とi18n


Next.jsの静的サイト生成(SSG)機能を活用することで、i18n対応の多言語サイトを効率的に構築できます。このセクションでは、SSGとi18nの連携方法について詳しく説明します。

1. SSGで言語ごとのページを生成


Next.jsのgetStaticPathsを使用して、すべての言語バリエーションを事前に生成します。

src/pages/[locale]/index.js

import { useTranslation } from 'react-i18next';

export default function Home() {
  const { t } = useTranslation();

  return (
    <div>
      <h1>{t('welcome')}</h1>
      <p>{t('about')}</p>
    </div>
  );
}

export async function getStaticPaths() {
  const locales = ['en', 'ja']; // サポートする言語
  const paths = locales.map((locale) => ({ params: { locale } }));

  return {
    paths,
    fallback: false, // 未定義のパスは404を返す
  };
}

export async function getStaticProps({ params }) {
  return {
    props: {
      locale: params.locale, // 言語情報を渡す
    },
  };
}

コードのポイント

  • locales.map():各言語ごとのURLパスを生成します。
  • getStaticPaths:静的ページをビルド時に作成するためのパスを定義します。
  • getStaticProps:ページのプロパティとしてlocaleを渡し、各言語に対応したデータを供給します。

2. 翻訳データの適用


i18nextを利用して言語に基づいた翻訳データをロードします。getStaticPropsで取得したlocaleを用いて、対応する言語ファイルを選択します。

例:翻訳の適用

export async function getStaticProps({ params }) {
  const translations = await import(`../../locales/${params.locale}/common.json`);

  return {
    props: {
      locale: params.locale,
      translations,
    },
  };
}

この例では、params.localeに基づいて翻訳データを動的にインポートします。

3. ローカルキャッシュの活用


SSGでは、すべての翻訳データがビルド時に静的ファイルとして生成されます。この特性を活かし、ページ読み込み速度を向上させることができます。言語切り替えを行ってもサーバーリクエストを必要としないため、ユーザー体験が向上します。

4. SSGとi18nのメリット

  • 高速なページ表示:すべてのページが静的に生成されるため、レンダリング速度が向上します。
  • SEO対策:各言語ごとに独立したページが生成されるため、検索エンジンに最適化されたURLを提供できます。
  • シンプルなデプロイ:静的ファイルとしてビルドされるため、CDNを利用した簡単なデプロイが可能です。

5. 動作確認


以下の手順でビルドプロセスを実行し、正しい動作を確認します:

npm run build
npm start

ブラウザで各言語のURLを訪問し、適切な翻訳が表示されていることを確認してください。

このセクションでは、SSGを利用してi18n対応サイトを効率的に構築する方法を学びました。次は、UX向上のための工夫について説明します。

ユーザー体験を向上させる工夫


多言語対応サイトにおいて、ローカリゼーション(i18n)を活用したユーザー体験(UX)の向上は非常に重要です。このセクションでは、言語切り替えやコンテンツの最適化を通じて、訪問者にとって便利で直感的なサイトを構築するための工夫を紹介します。

1. 自動的な言語検出


ユーザーのブラウザ設定や地理情報を基に、最適な言語を自動的に選択します。

ブラウザの言語設定を取得する例

import { useEffect } from 'react';
import { useRouter } from 'next/router';
import { useTranslation } from 'react-i18next';

export default function LanguageDetector() {
  const router = useRouter();
  const { i18n } = useTranslation();

  useEffect(() => {
    const browserLanguage = navigator.language.split('-')[0]; // 言語コードを取得
    if (['en', 'ja'].includes(browserLanguage)) {
      i18n.changeLanguage(browserLanguage);
      router.push(`/${browserLanguage}`);
    } else {
      router.push('/en'); // デフォルト言語
    }
  }, [router, i18n]);

  return null;
}

このコードを使用すると、訪問者の言語に基づいて自動的に適切なページにリダイレクトします。

2. 言語切り替えのスムーズな体験


言語切り替えボタンを使用する際、ページをリロードせずにコンテンツを切り替えることで、スムーズなユーザー体験を提供します。

言語切り替えコンポーネント例

import { useRouter } from 'next/router';
import { useTranslation } from 'react-i18next';

export default function LanguageSwitcher() {
  const { i18n } = useTranslation();
  const router = useRouter();

  const changeLanguage = (lng) => {
    i18n.changeLanguage(lng);
    router.push(`/${lng}${router.asPath.replace(/^\/\w{2}/, '')}`);
  };

  return (
    <div>
      <button onClick={() => changeLanguage('en')}>English</button>
      <button onClick={() => changeLanguage('ja')}>日本語</button>
    </div>
  );
}

この例では、現在のページURLを維持しながら言語を切り替えます。

3. ユーザー固有の言語設定を保存


言語設定をブラウザのクッキーやローカルストレージに保存し、次回訪問時に適用します。

言語設定を保存する例

const saveLanguagePreference = (language) => {
  localStorage.setItem('preferredLanguage', language);
};

const getSavedLanguagePreference = () => {
  return localStorage.getItem('preferredLanguage') || 'en';
};

保存した設定を利用して言語を初期化することで、ユーザーに一貫した体験を提供できます。

4. コンテンツの文化的最適化


単に翻訳するだけでなく、ターゲット言語に応じた文化的要素を取り入れたコンテンツを提供します。例えば:

  • 通貨や日付形式をローカライズする。
  • 画像やグラフィックを文化的に適切なものに変更する。

通貨形式の例(Intl.NumberFormat

const formatCurrency = (amount, locale) => {
  return new Intl.NumberFormat(locale, { style: 'currency', currency: 'USD' }).format(amount);
};

console.log(formatCurrency(1000, 'en-US')); // $1,000.00
console.log(formatCurrency(1000, 'ja-JP')); // ¥1,000

5. アクセシビリティの確保

  • すべてのテキストコンテンツに適切なlang属性を設定。
  • 翻訳内容をスクリーンリーダーに配慮した形で提供。

6. SEOの強化

  • 各言語のページに適切な<link rel="alternate" hreflang="...">タグを設定し、検索エンジンが正しい言語バージョンを認識できるようにします。
  • メタディスクリプションやタイトルタグを各言語で最適化。

7. フィードバック機能の実装


多言語対応のUIやコンテンツに対するユーザーのフィードバックを収集し、改善に役立てます。

これらの工夫を通じて、ローカリゼーションを活用した快適なユーザー体験を提供することが可能になります。次のセクションでは、i18n設定時に起こり得る問題とその解決策について解説します。

トラブルシューティング


Next.jsでローカリゼーション(i18n)を設定する際には、いくつかの問題が発生する可能性があります。このセクションでは、よくある問題とその解決策を紹介します。

1. 翻訳が適用されない


原因i18nextreact-i18nextの設定が正しくない場合があります。また、翻訳ファイルのキーが不足していることも考えられます。

解決策

  • i18n.jsの設定を確認し、正しい言語コードが設定されているか確認します。
  • 翻訳ファイルのキーが一致しているか、以下の例を確認します:
// common.json
{
  "welcome": "Welcome"
}

ページでの呼び出し:

t('welcome');

2. URLでの言語切り替えが機能しない


原因router.pushのパスやgetStaticPathsの設定が正しくない場合があります。

解決策

  • getStaticPathsで指定したパスが正しいか確認してください。
  • 言語コードがURL内に含まれているかを確認します。

3. デフォルト言語が正しく設定されない


原因:Next.jsのi18n設定やi18nextのデフォルト言語設定が不一致の場合があります。

解決策

  • next.config.jsdefaultLocalei18n.jslngプロパティが一致しているか確認してください。

4. SEOの設定が適切に機能しない


原因<link rel="alternate" hreflang="...">タグが不足している場合があります。

解決策

  • next/headを使用して、以下のようにhreflangタグを設定します:
import Head from 'next/head';

export default function SEO() {
  return (
    <Head>
      <link rel="alternate" href="https://example.com/en" hreflang="en" />
      <link rel="alternate" href="https://example.com/ja" hreflang="ja" />
    </Head>
  );
}

5. ビルド時のエラー


原因getStaticPathsgetStaticPropsで不正なデータが返されている可能性があります。

解決策

  • ログを確認し、正しいパスとデータが生成されているかデバッグします。
  • すべてのローカリゼーションファイルが存在しているか確認してください。

6. コンテンツの一部が翻訳されない


原因:一部の翻訳キーが不足している、または翻訳ファイルが正しくロードされていない可能性があります。

解決策

  • すべてのキーが翻訳ファイルに含まれているか確認してください。
  • ファイルのロードエラーがないかチェックします。

7. ユーザーが意図した言語にリダイレクトされない


原因:ブラウザの言語設定を正しく取得できていない可能性があります。

解決策

  • navigator.languageまたはaccept-languageヘッダーを利用して言語を取得し、ログで確認します。

これらのトラブルシューティングを参考にして、i18n設定をスムーズに進めてください。最後にまとめを行います。

まとめ


本記事では、Next.jsでのローカリゼーション(i18n)の設定と実践的な活用方法について解説しました。Next.jsのネイティブなi18n機能を利用することで、多言語対応サイトの構築が効率化され、ユーザー体験やSEOの向上に寄与します。

具体的には、以下のポイントを学びました:

  • i18nの概要とその利点
  • 基本的な設定と言語ファイルの管理
  • 動的ルーティングや静的サイト生成(SSG)との連携
  • ユーザー体験を向上させるための工夫
  • よくある問題とその解決方法

これらの知識を活用することで、グローバルなユーザーに対応するNext.jsサイトを自信を持って構築できるようになります。この記事を参考に、ぜひ実際のプロジェクトでi18nを活用してみてください!

コメント

コメントする

目次