[Next.js] 多言語

2022-04-01 hit count image

TypeScriptベースのNext.jsにnext-translateを使って多言語をサポートする方法について説明します。

概要

今期あのブログポストではTypeScriptをベースにしたNext.jsプロジェクトにnext-translateを使って多言語をサポートする方法について説明します。

ここで紹介するソースコードは下記のリンクで確認できます。

ブログリスト

このブログポストはシリーズで作成されています。次はNext.jsのシリーズリストです。

TypeScriptベースのNext.jsプロジェクトを生成

TypeScriptが適用されたNext.jsプロジェクトでnext-translateを使って多言語をサポートする方法を確認するため、次のコマンドを実行してTypeScriptが適用されたNext.jsプロジェクトを生成します。

npx create-next-app --typescript my-app

next-translateのインストール

Next.jsプロジェクトでnext-translateを使って多言語をサポートするため、next-translateをインストールする必要があります。次のコマンドを使ってnext-translateをインストールします。

npm install --save next-translate

next-translateの設定

このようにインストールしたnext-translateを使うため、next-translateを設定する必要があります。まず、./next.config.jsファイルを開いて次のように修正します。

const nextTranslate = require('next-translate');

module.exports = nextTranslate();

そして、./i18n.jsonファイルを生成して次のように修正します。

{
  "locales": ["ja", "en", "ko"],
  "defaultLocale": "en",
  "localeDetection": false,
  "pages": {
    "*": ["common"]
  }
}

今回のブログポストではja(Japanese), en(English), ko(Korean)を支援する予定です。そして、基本言語はenを設定しました。

{
  "locales": ["ja", "en", "ko"],
  "defaultLocale": "en",
  ...
}

Next.jsが自動でブラウザの言語を感知して当該言語を表示することを防止するため、localeDetectionfalseで設定しました。

{
  ...
  "localeDetection": false,
  ...
}

next-translateは全てのページで共通で使う言語セットと特定したページ飲みで使える言語セットを提供することができます。

{
  ...
  "pages": {
    "*": ["common"]
  }
}

今回のブログでは全てのページ(*)で共通で使える言語セットをcommonに保存して提供する予定です。

言語ファイル

今度は多言語を提供するため言語ファイルを生成してみましょう。./locales/en/common.jsonファイルを開いて下記のように修正します。

{
  "Japanese": "Japanese",
  "English": "English",
  "Korean": "Korean"
}

そして、./locales/ja/common.jsonファイルを生成して次のように修正します。

{
  "Japanese": "日本語",
  "English": "英語",
  "Korean": "韓国語"
}

最後に、./locales/ko/common.jsonファイルを生成して次のように修正します。

{
  "Japanese": "일본어",
  "English": "영어",
  "Korean": "한국어"
}

Next.jsで多言語をサポート

このように設定したnext-translateを使ってNext.jsプロジェクトで多言語をサポートする方法について説明します。./pages/index.tsxファイルを開いて次のように修正します。

...
import useTranslation from 'next-translate/useTranslation';

const Home: NextPage = () => {
  const { t } = useTranslation();

  return (
    <div className={styles.container}>
      ...
      <main className={styles.main}>
        ...
        <h2>{t('common:Japanese')}</h2>
        <h2>{t('common:English')}</h2>
        <h2>{t('common:Korean')}</h2>
        ...
      </main>
      ...
    </div>
  );
};

next-translateが提供するuseTranslationフックのt関数を使うと多言語を提供することができます。

t('common:Japanese')

t関数を使う時にはどの言語ファイル(common)のどの単語(Japanese)を使うか渡す必要があります。

多言語確認

Next.jsで適用したnext-translateが上手く動作してるか確認するため、次のコマンドを実行してNext.jsプロジェクトを実行します。

npm run dev

実行されたら、ブラウザでhttp://localhost:3000/を開いてみると次のように多言語の基本言語であるenが表示されることが確認できます。

next-translate supports English

他の言語も上手く表示されるか確認するためhttp://localhost:3000/jaを開いてみると次のようにja言語が上手く表示されることが確認できます。

next-translate supports Japanese

次はhttp://localhost:3000/koを開いてみると次のようにko言語が上手く表示されることが確認できます。

next-translate upports Korean

テスト

Next.jsに適用したnext-translateをテストする方法について説明します。Next.jsにテスト環境を構築する方法については以前のブログポストを確認してください。

以前のブログポストで作成したテストコードは次のようになります。

import { render, screen } from '@testing-library/react';
import Home from '../../pages/index';

describe('Home', () => {
  it('renders a heading', () => {
    const { container } = render(<Home />);

    const heading = screen.getByRole('heading', {
      name: /welcome to next\.js!/i,
    });

    expect(heading).toBeInTheDocument();

    expect(container).toMatchSnapshot();
  });
});

このコードを次のコマンドを使って実行します。

npm run test

そしたらスナップショットテスト結果が./test/index/__snapshots__/index.test.tsx.snapファイルに保存されることが確認できます。このファイルを開いてみると次のように言語が上手く表示されないことが分かります。

<h2>
  common:Japanese
</h2>
<h2>
  common:English
</h2>
<h2>
  common:Korean
</h2>

これを表示されて欲しい言語に変えるためには次のようにI18nProviderと言語ファイルを提供する必要があります。


...
import commonEN from '../../locales/en/common.json';
import I18nProvider from 'next-translate/I18nProvider';

describe('Home', () => {
  it('renders a heading', () => {
    const { container } = render(
      <I18nProvider lang="en" namespaces={{ common: commonEN }}>
        <Home />
      </I18nProvider>
    );
    ...
  });
});

このように修正してスナップショットテストをアップデートして、スナップショット結果ファイル(./test/index/__snapshots__/index.test.tsx.snap)を再び開いてみると、次のように私たちが設定した言語が上手く表示されることが確認できます。

<h2>
  Japanese
</h2>
<h2>
  English
</h2>
<h2>
  Korean
</h2>

完了

今回のブログポストではTypeScriptをベースにしたNext.jsプロジェクトでnext-translateを使って多言語を提供する方法についてみてみました。また、Jestを使うテスト環境でnext-translateをテストする方法についても確認しました。

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。

Posts