Next.js アプリを国際化（i18n）する方法

「時代はまさにグローバル」とあえて言われることも無くなるぐらい、世界との繋がりが普通になっている現在。

とは言いつつも、アプリ開発するときに、英語や他の言語の対応はついつい後回しになってしまいますよね…。

だが、しかし！

Next.js でのアプリ開発では、国際化を簡単に実装することが可能です。

その方法を今回紹介します。

## 「i18n」ってなに？

i18n とは、「 IntenationalizationN 」 の略語です。
「i」と「N」の間に、１８文字あるので、i18n となります。

複数の国の言語や文化に合わせて適応させる手段です。

読み方は、

- インターナショナライゼーション
- アイ イチ ハチ エヌ

今回は言語の国際化に焦点を合わせて、記事を記載しています。

## この記事のミッション

Next.js アプリで、日本語と英語に対応したアプリの開発方法を説明します。

この記事を読まれた皆さんのアプリが、国際化対応されることが目的です。

## この記事の対象

- NextJs でアプリを開発している人
- NextJs でアプリの開発を、今からはじめようと思っている人

特に、「今からはじめようと思われている方」へ。

この記事をみて開発当初に設定しておくことをオススメします。
開発の中盤から i18n 化をしようとすると、一つ一つ追加していくのがとてもしんどいです。

## サンプルページ／コード

### サンプルページ

言語の切り替えが体験できるページです。

https://i18n-sample.vercel.app/

### Githubリポジトリ

https://github.com/AkiUnleash/i18n-sample

## 手順

手順は大きく分けると４つのステップになります。
それではやっていきましょう。

### ステップ ①：next.config.js の設定

まずは、何ヶ国語対応させるのか等の設定が必要です。  
next.config.js に設定を書いていきましょう。

設定方法には２通りの方法があります。
(サンプルは、サブパスの方法を採用しています。)

#### サブパスで、言語を選択する方法

サブパスで言語を判断する方法です。

```javascript:next.config.js
/**
 * InternationnalizationN
 */
module.exports = {
  i18n: {
    locales: ["en", "ja"],
    defaultLocale: "ja"
  },
}
```

上記のように設定すると、以下のような URL になります。

```bash
# 日本語 … defaultLocalをjaにしているため、ドメインが日本語
https://example.com

# 英語 … パスにenを追加することで英語と識別。
https://example.com/en
```

#### ドメイン毎に言語を変更する方法

```javascript:next.config.js
/**
 * InternationnalizationN
 */
module.exports = {
  i18n: {
    locales: ["en", "ja"],
    defaultLocale: "ja",
    domains: [
      {
        domain: 'example.en',
        defaultLocale: 'en',
      },
      {
        domain: 'example.com',
        defaultLocale: 'ja',
      },
  }
}
```

上記のように設定すると、以下のような URL になります。

```bash
# 日本語 … defaultLocalをjaにしているため、ドメインが日本語
https://example.com

# 英語 … パスにenを追加することで英語と識別。
https://example.ja
```

### ステップ ②：文字列を言語別に準備する。

日本語用語と英語用の文字列をオブジェクトします。
TypeScript では、type で事前に型を作ることで、多言語での漏れを防ぐことをおすすめします。

```javascript:i18n.ts
export type i18n = {
  greeting: string
  language: string
};

/**
 * 日本語一覧
 */
export const ja: i18n = {
  greeting: "日本語ページへようこそ！",
  language: "日本語",
};

/**
 * 英語一覧
 */
export const en: i18n = {
  greeting: "Welcome to English page!",
  language: "English",
};
```

## ステップ ③： URL で言語を判別する

判別するには以下の２つの方法があります。

### useRouter を使用する方法

useRouter にてリターンされる、locale で言語を判断しています。

```javascript:i18n.ts
import { useRouter } from "next/router";

/**
 * [https://example.com] の場合、ja
 * [https://example.com/en] の場合、en
 * が locale の中に返されます。
 */
const { locale } = useRouter();
const t = locale === "en" ? en : ja;
```

### getStaticProps を使用する方法

getStaticProps に含まれる locale を使用する方法です。

静的ファイルを事前に生成するため、この方法の方が SEO 対策にも繋がりますし、良いのではないかと考えています。

```javascript:i18n.ts
/**
 * [https://example.com] の場合、ja
 * [https://example.com/en] の場合、en
 * が locale の中に返されます。
 */
export function getStaticProps({ locale }) {
  const i18nText = locale === "en" ? en : ja;
  return { props: { i18nText } };
}
```

## ステップ ④： コンポーネントに反映する。

それでは最後に、コンポーネントに反映していきましょう。
getStaticProps から受け取ったデータを反映しています。

分かりやすいように、ステップ ②〜④ を一つのコードにしています。

これで URL 別に言語対応が完成しました。

```javascript:index.tsx
import { NextPage } from 'next'

type Props = { i18nText: i18n }

/**
 * ホームを画面のコンポーネント
 */
const Home: NextPage<Props> = ({ i18nText }) => {
  return (
    <>
      <h1> {i18nText.greeting} </h1>
      <div> {i18nText.language} </div>
    </>
  )
}

/**
 * 静的ファイルを事前に作成。
 */
export function getStaticProps({ locale }) {
  const i18nText = locale === "en" ? en : ja;
  return { props: { i18nText } }
}

type i18n = {
  greeting: string
  language: string
};

/**
 * 日本語一覧
 */
export const ja: i18n = {
  greeting: "日本語ページへようこそ！",
  language: "日本語",
};

/**
 * 英語一覧
 */
export const en: i18n = {
  greeting: "Welcome to English page!",
  language: "English",
};

export default Home
```

## 補足： Link から画面遷移する方法

Link タグの locale に言語の種類を登録すると、画面遷移も可能です。

```javascript
import Link from "next/link";

// 英語画面へ遷移
<Link href="/" locale="en">
  <a> Move to English </a>
</Link>;

// 日本語画面へ遷移
<Link href="/" locale="ja">
  <a> 日本語へ移行 </a>
</Link>;
```

## 実際のコードを見て、内容を再確認してみてください。

この記事の上部にも掲載していますが、以下サンプルで用意したコードです。
以下３つのファイルのみ見てもらえれば、内容がしっかりと把握できると思います。

next.config.js … 言語の種類等の設定 (ステップ ①)
service/i18n.ts … i18n の詳細設定 （ステップ ②③）
pages/index.tsx … コンポーネントを表示 （ステップ ④）

https://github.com/AkiUnleash/i18n-sample

## おわりに。

ここまで読んでいただき有難うございました。
皆さんの力に少しでもなれたなら幸いです。

このような記事を今後も投稿していきたいと考えています。
[@Aki Unleash | Twitter](https://twitter.com/AkiUnleash)

## 参考にさせていただいた記事

https://nextjs.org/docs/api-reference/next/router

https://developer.mozilla.org/ja/docs/Glossary/I18N