Skip to content

[user]多言語対応 #1963

@hikahana

Description

@hikahana

開発目的

今年からのユーザー画面大幅リファクタリングの中で対応できていなかった多言語対応に関して、参加団体アンケートからも何件か英語バージョンが欲しいという意見が来ていた。以下参照されたし
https://docs.google.com/forms/d/14OYKuWPKZNrBBvqfte7HKesgzhVnLANqOl3emeVVjoM/edit#responses

現在のユーザー画面は日本語のみの説明文しか載っていないので最低限、日本語/英語の2言語に対応する。要望が多ければその他言語も増やす可能性あり。

考えられる開発内容

i18nというライブラリを使用して実装を行う。
日本語と英語のファイルをlocales配下に用意し、/jaと/enで言語切り替えを行えるようにするものである。

めんどいのでたたき台をgptにぶん投げ。一部修正の形で

ディレクトリ構成

user/
├── next.config.js
├── next-i18next.config.js
├── public/
│   └── locales/
│       ├── ja/
│       │   └── common.json
│       └── en/
│           └── common.json
├── src/
│   ├── pages/
│   │   ├── _app.tsx
│   │   └── index.tsx
│   └── components/
│       └── LanguageSwitcher.tsx
└── package.json

実装手順

  1. 依存の追加

    docker compose run --rm user npm i next-i18next react-i18next i18next
    # (必要なら型)
    docker compose run --rm user npm i -D @types/i18next
  2. next-i18next.config.js を作成

    // next-i18next.config.js
    /** @type {import('next-i18next').UserConfig} */
    module.exports = {
      i18n: {
        defaultLocale: 'ja',
        locales: ['ja', 'en'],
      },
    };
  3. next.config.js から上記を読み込む

    // next.config.js
    const { i18n } = require('./next-i18next.config');
    /** @type {import('next').NextConfig} */
    const nextConfig = { i18n };
    module.exports = nextConfig;
  4. 翻訳ファイルを配置
    これは一例です。
    本来は実装されているすべての日本語分の内容をここに記載する必要があります。

    // public/locales/ja/common.json
    { "title": "これはタイトル", "back-to-home": "ホームに戻る" }
    // public/locales/en/common.json
    { "title": "This is title", "back-to-home": "Back to Home" }
  5. 差し替え作業
    4で作成した翻訳ファイルが適用されるように今までのすべての文言を変数名に変えます。
    頑張ってください

  6. _app.tsxappWithTranslation でラップ

    // src/pages/_app.tsx
    import type { AppProps } from 'next/app';
    import { appWithTranslation } from 'next-i18next';
    
    function App({ Component, pageProps }: AppProps) {
      return <Component {...pageProps} />;
    }
    export default appWithTranslation(App);
  7. ページで serverSideTranslations を呼んで辞書を注入(SSG/SSR)

    // src/pages/index.tsx
    import { useTranslation } from 'next-i18next';
    import type { GetStaticProps } from 'next';
    import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
    
    export default function Home() {
      const { t } = useTranslation('common');
      return <h1>{t('title')}</h1>;
    }
    
    export const getStaticProps: GetStaticProps = async ({ locale }) => ({
      props: {
        ...(await serverSideTranslations(locale ?? 'ja', ['common'])),
      },
    });
  8. 言語切替 UI(URL ロケール切替)

    // src/components/LanguageSwitcher.tsx
    'use client';
    import { useRouter } from 'next/router';
    
    export function LanguageSwitcher() {
      const router = useRouter();
      const switchTo = (locale: 'ja' | 'en') =>
        router.push(router.asPath, router.asPath, { locale });
      return (
        <div>
          <button onClick={() => switchTo('ja')} disabled={router.locale === 'ja'}>日本語</button>
          <button onClick={() => switchTo('en')} disabled={router.locale === 'en'}>English</button>
        </div>
      );
    }

参考文献

https://zenn.dev/mybest_dev/articles/324aed92f8086f

https://locize.com/blog/next-i18next

考えられる開発時間

これは作業量が多いので時間がどうしてもかかります。
タスク難易度はそこまで高くない。日本語をすべて英語にしたものを用意するので最低3hかそれ以上と思われ。

備考

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions