UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Next.js】next-translateのbuild step以外でNext.jsページを翻訳する

next-translateを使ったNext.jsページの翻訳を行った

uga-box.hatenablog.com

この時は「build step」を使ったが、他にもやりかたもあるようなので調べる

https://github.com/vinissimus/next-translate#13-do-i-need-this-build-step-is-there-an-alternative

上のリンクによると2つのやり方がある

  1. appWithI18nを使う
    🔴 Automatic Static Optimizationではない
    🟢 設定が簡単
  2. 各ページにnamespaceをロードするhelperを使用する
    🟢 Automatic Static Optimizationになる
    🔴 設定が難しい

せっかくならばAutomatic Static Optimizationを利用したいので、2.の方法をやってみる

手順

next-translateのインストール

$ npm i -D next-translate

i18n.jsonを用意する

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

/localesjsonファイルを用意する

.
├── en
│   ├── common.json
│   └── home.json
└── ja
    ├── common.json
    └── home.json

common.json

{
  "title": "Hello world",
  "variable-example": "Using a variable {{count}}"
}

next.config.jsの修正

const { locales, defaultLocale } = require('./i18n.json')

module.exports = {
  i18n: { locales, defaultLocale },
}

_app.jsの修正

import React from 'react'
import I18nProvider from 'next-translate/I18nProvider'
import { useRouter } from 'next/router'

import '../styles.css'

export async function loadNamespaces(namespaces, lang) {
  let res = {}
  for (let ns of namespaces) {
    res[ns] = await import(`../locales/${lang}/${ns}.json`).then(
      (m) => m.default
    )
  }
  return res
}

export default function MyApp({ Component, pageProps }) {
  const router = useRouter()

  return (
    <I18nProvider lang={router.locale} namespaces={pageProps._ns}>
      <Component {...pageProps} />
    </I18nProvider>
  )
}

ページを作成する
pages_/example.js

import React from 'react'
import useTranslation from 'next-translate/useTranslation'

import { loadNamespaces } from './_app'

export default function Home() {
  const { t } = useTranslation()
  const description = t('home:description')

  return (
    <>
      <p>{description}</p>
    </>
  )
}

export async function getStaticProps({ locale }) {
  return {
    props: {
      _ns: await loadNamespaces(['common', 'home'], locale),
    },
  }
}

/pagesを.gitignoreに入れる必要ないし、ビルド前フォルダを利用することがなくなったので個人的にはこちらの方がよさそう