🌍

たった10分で Next.js アプリを日本語対応させた話

2021/01/07に公開2

こんにちは。 @yuyaaaar です。

1日に何回投稿するねんって話なんですが、ご容赦ください。

今回は、自分の運用しているサイト を秒速で i18n 対応できたので、そのやり方を書いていきます。

Next.js 10 以前は、next-i18nextみたいなパッケージを使って、ちょっとハッキーなことをしないとなかなか i18n 対応 + Next.js の恩恵をフルで受ける方法はなかったのですが、Next.js 10 からは i18n はオフィシャル的にサポートされました。

やり方はめちゃくちゃ簡単で、 next.config.js にサポートしたいロケールとデフォルトを指定するだけ。

module.exports = {
  i18n: {
    locales: ["en", "ja"],
    defaultLocale: "en",
  },
};

以上。これで、例えば loggnog.com の場合、

デフォルトは英語で loggnog.com

日本語の場合は loggnog.com/ja

で同じページをアクセスすることができます。しかもちゃんとロケールごとに静的生成されるのもいいですよね。

どうやってユーザーのロケールを判断しているかというと、Accept-Language を確認して、それ相応のロケールに自動的にURLを変えてくれます。

ただ一つネックなのは、↑の自動ルーティングはアプリケーションルートでしか行われません。ということは、example.com のみ検知され、 example.com/app とかの場合だと検知してくれません。ですが、今後需要があれば nested routes の自動検知対応も視野に入れるそうです。

翻訳を加えるには、まず useRouter からロケールを摘出します

import { useRouter } from 'next/router'

const App = () => {
   const { locale } = useRouter() // 現在のロケールを表示してくれる
   // ..
}

まぁここからは翻訳ライブラリを使ったりしてもいいのですが、自分の場合はシンプルだったので、 en.jsja.js というファイルを作り、その中にオブジェクトとして翻訳を入れちゃってます。

// ja.js

export default {
  SUBTITLE: "「満足」を可視化しよう",
  TO_DASHBOARD: "ダッシュボードへ",
  // ...
}

// en.js
export default {
  SUBTITLE: "Visualize your customer happiness.",
  TO_DASHBOARD: "Go to dashboard",
  // ...
}

そして、これらのファイルをインポート、ロケールを照らし合わせて適切な翻訳を引っ張ってくる、ていう仕組み。

import { useRouter } from 'next/router'
import en from "../../locales/en";
import ja from "../../locales/ja";

const App = () => {
   const { locale } = useRouter()
   
   const t = locale === "en" ? en : ja;
   
   return (
      <div>
         ...
	 <h1>{t.SUBTITLE}</h1>
	 <button>{t.TO_DASHBOARD}</button>
      </div>
   )
}

おまけですが、毎回ルーターモジュールと翻訳ファイルをインポートするのもめんどいので、 hook にしちゃいましょう

// hooks/useLocale.ts

import en from "../../locales/en";
import ja from "../../locales/ja";
import { useRouter } from "next/router";

export const useLocale = () => {
  const { locale } = useRouter();

  const t = locale === "en" ? en : ja;

  return { locale, t };
};

これだけで、二か国語対応が完了しちゃいます。

以上!

Discussion

koji sayamakoji sayama

ありがとうございます!!大変参考になる記事でした

hookを使用した際のimport方法とその際にはどのようにしてに、ロケールを照らし合わせて行くのかについても追記していただき教えていただけると大変助かります!!

またコンポーネント内で使用するにはどうしたら良いのでしょうか?

yuyao17yuyao17

見逃してましたすみません!!

import 方法・使い方は、

import { useLocale } from "path/to/hooks/useLocale";

const App = () => {
   const { t, locale } = useLocale();
   
   return (
      <div>{t.WELCOME_1}</div>
   )
}

です!ロケールの照らし合わせは useLocale 内の useRouter で自動的に取得できるようにしてます!