1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

これ一つでOK!Next.jsのApp Routerで簡単に多言語対応を組み込む方法

Posted at

はじめに

ウェブアプリケーションを複数の言語に対応させることは、グローバルなユーザーを対象とする上で欠かせない要素です。
Next.jsは、サーバーサイドレンダリングやクライアントサイドレンダリングを柔軟に組み合わせることで、多言語対応を効率的に実現できるフレームワークです。

本記事では、Next.jsのApp Routerを用いて多言語対応(i18n)を実装する方法を詳しく解説します。
この記事を読むことで、以下のことがわかります:

  • 多言語対応の基本的な考え方
  • i18nextやreact-i18nextを使った翻訳機能の実装方法
  • サーバーコンポーネントとクライアントコンポーネントでの活用方法
  • よくある課題とその解決策

初心者から中級者までを対象に、手順を丁寧に説明しますので、初めてi18nを導入する方でも安心して取り組めます。
これだけ読めば、他の記事を参照する必要はありません。それでは、始めましょう。


1. i18nを導入するメリット

  • 複数の言語を簡単にサポートできる
  • ユーザーが使用する言語に合わせた表示が可能
  • グローバルな製品展開に必須の機能

2. プロジェクト初期セットアップ

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

まずは新規にNext.jsのプロジェクトを作成します。

npx create-next-app my-app

その後、cdで作成されたディレクトリに移動し、開発用サーバーを立ち上げます。

npm run dev
# or
yarn dev

2-2. ディレクトリ構成の確認

App Routerでは、appディレクトリでページやレイアウトを定義します。典型的な構成例は以下の通りです。

my-app/
├─ app/
│   ├─ layout.tsx
│   ├─ page.tsx
│   └─ ...他のルート
├─ public/
├─ package.json
├─ next.config.js
└─ ...

3. i18nextとreact-i18nextのインストール

i18n機能を使うために、i18nextおよびReact向けのreact-i18nextを導入します。

npm install i18next react-i18next
# or
yarn add i18next react-i18next

4. i18nの設定ファイル

4-1. i18nのコンフィグ

ルートディレクトリにi18n.js(またはi18n.ts)ファイルを作成し、i18nextの初期化設定を行います。

// i18n.js

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

import enCommon from './public/locales/en/common.json';
import jaCommon from './public/locales/ja/common.json';

i18n.use(initReactI18next).init({
  fallbackLng: 'en',
  supportedLngs: ['en', 'ja'],
  resources: {
    en: {
      common: enCommon,
    },
    ja: {
      common: jaCommon,
    },
  },
  ns: ['common'],
  defaultNS: 'common',
});

export default i18n;
  • fallbackLng: 言語が指定されない場合のデフォルト言語
  • supportedLngs: サポートする言語一覧
  • resources: 翻訳ファイルをまとめたオブジェクト

4-2. 翻訳ファイルの配置

翻訳ファイルはpublic/locales/{言語コード}/common.jsonの形で配置するのが一般的です。例として以下のような構成を用意します。

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

ja/common.jsonの例:

{
  "hello": "こんにちは",
  "siteTitle": "サンプルサイト"
}

en/common.jsonの例:

{
  "hello": "Hello",
  "siteTitle": "Sample Site"
}

5. App Routerでの言語切り替え方法

App Routerを使う場合、ディレクトリ名やルート定義を工夫することでURLにロケールを含めるアプローチが取りやすくなります。

ディレクトリ例

app/
├─ [lang]/
│  ├─ layout.tsx
│  └─ page.tsx
├─ layout.tsx
└─ page.tsx
  • [lang]ディレクトリを用意して、動的な言語コードをURLパラメータとして扱えます。
  • 必要に応じて、トップレベルのlayout.tsxと組み合わせて管理しましょう。

6. 各ページ・コンポーネントでの翻訳使用例

6-1. サーバーコンポーネントでの使用

App Routerでは、page.tsxlayout.tsxがサーバーコンポーネントとして動作することが多いです。ただし、直接useTranslationを呼べない場合があるため、必要に応じてクライアントコンポーネントを読み込む方法が使われます。

/app/[lang]/page.tsx 例

import SampleClient from './SampleClient';

export default function HomePage() {
  // 必要に応じてサーバーで言語コードを取得
  const lang = 'ja';

  return (
    <main>
      <SampleClient lang={lang} />
    </main>
  );
}

6-2. クライアントコンポーネントでの使用

クライアントコンポーネントで翻訳を利用するには、先頭に"use client";を宣言し、useTranslationを利用します。

"use client";

import { useTranslation } from 'react-i18next';

type Props = {
  lang: string;
};

export default function SampleClient({ lang }: Props) {
  const { t, i18n } = useTranslation('common');

  // 言語を変更したい場合
  if (i18n.language !== lang) {
    i18n.changeLanguage(lang);
  }

  return (
    <div>
      <h1>{t('hello')}</h1>
      <p>{t('siteTitle')}</p>
    </div>
  );
}

7. よくあるエラーと対処法

  1. 翻訳が適用されない

    • i18n.jsi18n.tsで設定を正しく行っているか確認
    • 翻訳ファイルのパスや名前に誤りがないか確認
  2. useTranslationがundefinedになる

    • react-i18nextをインストールしているか確認
    • i18n.init()の呼び出しやエクスポートに不備がないか確認
  3. 言語コードを切り替えられない

    • クライアントコンポーネントでi18n.changeLanguage(lang)を呼んでいるか
    • サーバーコンポーネントから正しいlangを渡しているか

8. まとめ

App Routerを利用したNext.jsプロジェクトでも、i18nextとreact-i18nextを用いることでシンプルかつ強力な多言語対応を実現できます。

ぜひ参考にして、グローバルなユーザーに対応したNext.jsプロジェクトを作り上げてください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?