Next.js および Nuxt.js における国際化のベストプラクティス
James Reed
Infrastructure Engineer · Leapcell

はじめに
今日のグローバル化されたデジタルランドスケープにおいて、多様なオーディエンスにリーチすることは、あらゆる成功するウェブアプリケーションにとって最重要です。これを達成するための重要なステップは、国際化、または i18n です。これは、エンジニアリングの変更を必要とせずに、アプリケーションが複数の言語や地域をサポートできるように設計および開発するプロセスです。Next.js や Nuxt.js のようなモダンなサーバーレンダリング JavaScript フレームワークで作業する開発者にとって、i18n を効果的に実装することは、単なる「あれば嬉しい」ものではなく、必要不可欠なものです。この記事では、Next.js と Nuxt.js で構築されたアプリケーションの国際化に関するベストプラクティスを掘り下げ、真にグローバルなユーザーエクスペリエンスを作成するための実践的なガイダンスとコード例を提供します。
国際化のコアコンセプト
実装の詳細に入る前に、i18n に関連するコアコンセプトについての共通理解を確立しましょう。
- 国際化 (i18n): アプリケーションのコードを変更することなく、さまざまな言語や地域に簡単に適応できるように設計および開発するプロセスです。それは、ローカライゼーションのためにアプリケーションを準備することです。
- ローカライゼーション (l10n): 国際化されたアプリケーションを特定のロケール(言語と地域の組み合わせ)に適応させるプロセスです。これには、テキストの翻訳、日付や数値のフォーマット、文化的ニュアンスの処理が含まれます。
- ロケール: ユーザーの言語と地域を定義する文字列識別子(例: アメリカ英語の場合は
en-US
、フランスのフランス語の場合はfr-FR
)。 - メッセージファイル/翻訳辞書: キーと値のペアのコレクションで、キーはテキスト文字列の一意の識別子を表し、値は特定のロケールの翻訳された文字列です。これらは通常、JSON、YAML、または PO ファイルです。
- 言語ネゴシエーション: ブラウザの設定、URL パラメータ、またはユーザーの選択に基づいて、ユーザーの好みの言語を決定するプロセスです。
- 動的ルーティング: ユーザーが好みの言語でコンテンツにアクセスできるように、ロケール情報を含めるように URL を構造化する方法(例:
/en/about
対/fr/about
)。
Next.js および Nuxt.js における国際化の実装
Next.js と Nuxt.js はどちらも i18n を優れたサポートしており、多くの場合、Next.js 用の react-i18next
や Nuxt.js 用の @nuxtjs/i18n
のような人気のあるライブラリを利用します。構文は異なる場合がありますが、基本的な原則は同様です。
i18n ライブラリの選択
Next.js の場合、react-i18next
は事実上の標準であり、SSR および SSG サポートをシームレスにするために next-i18next
パッケージと統合されることがよくあります。Nuxt.js の場合、コミュニティによって維持されている @nuxtjs/i18n
モジュールは、vue-i18n
を基盤とした包括的なソリューションを提供します。
設定とセットアップ
Next.js の next-i18next
と Nuxt.js の @nuxtjs/i18n
で例を示しましょう。
next-i18next
を使用した Next.js
-
インストール:
npm install next-i18next react-i18next i18next
-
next-i18next.config.js
: プロジェクトのルートに設定ファイルを作成します。// next-i18next.config.js module.exports = { i18n: { defaultLocale: 'en', locales: ['en', 'fr', 'es'], }, localePath: typeof window === 'undefined' ? require('path').resolve('./public/locales') : '/locales', reloadOnPrerender: process.env.NODE_ENV === 'development', };
-
_app.js
の統合:appWithTranslation
でアプリケーションをラップします。// pages/_app.js import { appWithTranslation } from 'next-i18next'; import nextI18nConfig from '../next-i18next.config'; function MyApp({ Component, pageProps }) { return <Component {...pageProps} />; } export default appWithTranslation(MyApp, nextI18nConfig);
-
翻訳ファイル:
public/locales/[locale]/common.json
(または他の名前空間)を作成します。// public/locales/en/common.json { "welcome": "Welcome!", "greeting": "Hello, {{name}}!" } // public/locales/fr/common.json { "welcome": "Bienvenue !", "greeting": "Bonjour, {{name}} !" }
@nuxtjs/i18n
を使用した Nuxt.js
-
インストール:
npm install @nuxtjs/i18n
-
nuxt.config.js
の設定: モジュールを追加し、設定します。// nuxt.config.js export default { modules: [ '@nuxtjs/i18n', ], i18n: { locales: [ { code: 'en', file: 'en.js', iso: 'en-US' }, { code: 'fr', file: 'fr.js', iso: 'fr-FR' }, { code: 'es', file: 'es.js', iso: 'es-ES' }, ], defaultLocale: 'en', langDir: 'locales/', // 翻訳ファイルのディレクトリ vueI18n: { fallbackLocale: 'en', }, strategy: 'prefix_and_default', // 'prefix_except_default', 'no_prefix', 'prefix' }, };
-
翻訳ファイル:
locales/[locale].js
を作成します。// locales/en.js export default { welcome: 'Welcome!', greeting: 'Hello, {name}!', }; // locales/fr.js export default { welcome: 'Bienvenue !', greeting: 'Bonjour, {name} !', };
コンテンツの翻訳
設定が完了したら、コンテンツの翻訳は簡単です。
Next.js (React コンポーネント)
// pages/index.js import { useTranslation } from 'next-i18next'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; export default function Home() { const { t } = useTranslation('common'); // 'common' は名前空間です return ( <div> <h1>{t('welcome')}</h1> <p>{t('greeting', { name: 'Alice' })}</p> </div> ); } export async function getStaticProps({ locale }) { return { props: { ...(await serverSideTranslations(locale, ['common'])), }, }; }
Nuxt.js (Vue コンポーネント)
<!-- pages/index.vue --> <template> <div> <h1>{{ $t('welcome') }}</h1> <p>{{ $t('greeting', { name: 'Alice' }) }}</p> </div> </template> <script> export default { // $i18n インスタンスへのアクセス mounted() { console.log(this.$i18n.locale); } } </script>
言語切り替え
ユーザーが言語を変更するためのメカニズムを提供することは重要です。これには通常、i18n ライブラリで現在のロケールを更新し、URL プレフィックスを使用している場合は、適切なローカライズされたルートに移動することが含まれます。
Next.js (言語切り替えコンポーネント)
// components/LanguageSwitcher.js import { useRouter } from 'next/router'; import Link from 'next/link'; export default function LanguageSwitcher() { const router = useRouter(); const { locales, locale: currentLocale } = router; return ( <div> {locales.map((locale) => ( <Link key={locale} href={router.asPath} locale={locale}> <a style={{ fontWeight: locale === currentLocale ? 'bold' : 'normal', marginRight: '10px' }}> {locale.toUpperCase()} </a> </Link> ))} </div> ); }
Nuxt.js (言語切り替えコンポーネント)
<!-- components/LanguageSwitcher.vue --> <template> <div> <NuxtLink v-for="locale in availableLocales" :key="locale.code" :to="switchLocalePath(locale.code)" :class="{ 'font-bold': locale.code === $i18n.locale }" class="mr-2" > {{ locale.code.toUpperCase() }} </NuxtLink> </div> </template> <script> export default { computed: { availableLocales () { return this.$i18n.locales.filter(i => i.code !== this.$i18n.locale) } } } </script>
動的ルーティングと SEO
next-i18next
と @nuxtjs/i18n
はどちらもローカライズされたルーティングを処理します。next-i18next
は Next.js の組み込み国際化ルーティングと直接統合し、@nuxtjs/i18n
は prefix_and_default
のようなさまざまな戦略を提供して URL 構造(例: /en/about
、/fr/about
、デフォルトの場合は /about
)を管理します。SEO のためには、各ローカライズされたバージョンのページに、それ自体を指す正規 URL と、他の言語バージョンを参照する hreflang
タグがあることを確認してください。これにより、検索エンジンはサイトの国際構造を理解するのに役立ちます。
日付、時刻、数値フォーマットの処理
テキスト翻訳を超えて、ロケールは日付、時刻、数値の表示方法にも影響します。これらの要素の堅牢なローカライゼーションには、ブラウザの組み込み Intl
API や moment.js
や date-fns
のようなライブラリを i18n ライブラリと組み合わせて使用してください。
const date = new Date(); const formattedDateEn = new Intl.DateTimeFormat('en-US').format(date); // 1/1/2023 const formattedDateFr = new Intl.DateTimeFormat('fr-FR').format(date); // 01/01/2023
サーバーサイドレンダリング (SSR) およびサーバーサイド生成 (SSG) の考慮事項
Next.js と Nuxt.js はどちらも SSR/SSG に優れており、SEO とパフォーマンスに有益です。i18n セットアップがクライアントで正しくハイドレーションされ、サーバーで正しい翻訳を取得することを確認してください。next-i18next
の serverSideTranslations
と @nuxtjs/i18n
の自動ロケール検出とメッセージローディングは、この目的のために設計されています。ビルド時に生成されたページ (SSG) は、ロケールごとにバージョンを作成する必要があります。
高度なプラクティスと考慮事項
- 翻訳管理ツール: 大規模なプロジェクトの場合は、Lokalise、Phrase、Crowdin のような翻訳管理システム (TMS) を検討してください。これらのツールは翻訳ワークフローを合理化し、共同翻訳を可能にし、多くの場合、翻訳ファイルのプル/プッシュを直接コードベースに統合します。
- 翻訳の遅延読み込み: すべてのロケールのすべての翻訳を最初にロードするのではなく、必要に応じて必要な言語ファイル、さらには特定の名前空間のみを遅延読み込みします。これにより、初期バンドルサイズが大幅に削減されます。
- フォールバックロケール: 障害となるロケールで翻訳キーが見つからない場合に備えて、必ずフォールバックロケール(例:
en
)を定義してください。 - 複数形: 言語にはそれぞれ異なる複数形ルールがあります。i18n ライブラリは通常、これを正しく処理するためのメカニズムを提供します。
react-i18next
: 翻訳ファイルでt('key', { count: 1 })
と複数形ルールを使用します。vue-i18n
:plural: 'Your item | Your items'
のような特別な構文を使用します。
- 右から左 (RTL) 言語: アラビア語やヘブライ語のような言語の場合、RTL レイアウトをサポートするように CSS を調整します。
html
タグにdir="rtl"
属性を動的に適用し、条件付きで異なる CSS ルールをロードする必要がある場合があります。 - SEO 最適化:
hreflang
タグに加えて、メタディスクリプション、タイトル、画像代替テキストも各言語バージョンに合わせてローカライズされていることを確認してください。これは、検索エンジンがサイトの国際構造を理解するのに役立ちます。 - 国際化のテスト: テキストのオーバーフロー、日付/数値フォーマット、RTL レイアウトに注意を払いながら、さまざまなロケールでローカライズされたコンテンツを徹底的にテストしてください。
結論
国際化の実装は、真にグローバルなアプリケーションを構築するための不可欠なステップです。Next.js および Nuxt.js の堅牢な機能と、専門の i18n ライブラリおよびベストプラクティスを活用することで、開発者はシームレスでローカライズされたユーザーエクスペリエンスを作成できます。これらの戦略を採用することで、アプリケーションは機能的であるだけでなく、文化的に関連性があり、世界中のオーディエンスがアクセスできるようになります。国際化は単なる翻訳ではありません。それは、ユーザー自身の言語と文化的な文脈でつながることなのです。