むーすけのブログ

GitHub X(Twitter) Qiita Zenn
「Next.jsを使ったプロジェクトにi18n対応をした話」のサムネイル画像

Next.jsを使ったプロジェクトにi18n対応をした話

2023/01/27

2023/02/23

なぜこれをやろうと思ったか

<html> element does not have a [lang] attribute

Lighthouseを使ってアクセシビリティの数値を確認したところ、上記のような警告が表示されていた。
これはhtmlタグにlang属性が設定されていないことを警告していて、解決するにはNext.js上でlocaleの設定をする必要があったため今回の対応を行なった。

解決方法

解決方法は至ってシンプルでnext.config.jsで以下のように記載してあげれば良い。

module.exports = {
  i18n: {
    locales: ['ja-JP'],
    defaultLocale: 'ja-JP',
  }
}

今回のように日本語だけの対応の場合は上記で問題ないが、複数言語の対応が必要になった際はSub-path RoutingDomain Routingの2種類の方法が取れる。

余談:複数言語の対応

Sub-path Routing

パスで区切って各言語ごとに提供するコンテンツを切り替える方法。

module.exports = {
  i18n: {
    locales: ['en-US', 'fr', 'nl-NL'],
    defaultLocale: 'en-US',
  },
}

例えば上記のような言語が設定されていた場合は以下のようなurlが有効になる。

  • /blog
  • /fr/blog
  • /nl-nl/blog

尚、defaultLocaleに設定されている言語は文字通りデフォルト設定になるので今回のケースで言うと/en-US/blogのようなパスは有効にはならない。
defaultLocaleに設定されている言語とは異なるものがAccept-Language headerで検出された場合はその言語に沿ったパスが表示されるようになる。
具体的には言語がフランス(fr)で/blogにアクセスした場合、/fr/blogにリダイレクトされる。

Domain Routing

ドメインで区切って各言語ごとに提供するコンテンツを切り替える方法。

module.exports = {
  i18n: {
    locales: ['en-US', 'fr', 'nl-NL', 'nl-BE'],
    defaultLocale: 'en-US',

    domains: [
      {
        domain: 'example.com',
        defaultLocale: 'en-US',
      },
      {
        domain: 'example.fr',
        defaultLocale: 'fr',
      },
      {
        domain: 'example.nl',
        defaultLocale: 'nl-NL',
        locales: ['nl-BE'],
      },
    ],
  },
}

Sub-path Routingが言語をパスで区切っているのに対してDomain Routingは名のとおり言語をドメインで区切っている。
具体的にはdomains内でdefaultLocaleとdomainを紐づけている。
こちらもSub-path Routingと同様にAccept-Language headerで検出された言語に応じたドメインが表示されるようになる。

最後に

今回やったことは多言語対応というよりかは日本語対応だけだったのでやることは少なかった。
多言語対応はやったことなかったが、事前に複数のやり方があることを知れたので学びだった。

書いてから思ったけど、余談の方が長くないか?

参考記事

https://nextjs.org/docs/advanced-features/i18n-routing
https://daily-dev-tips.com/posts/nextjs-add-lang-attribute-to-html-tag/

© 2022, mu-suke