i18next-vue と vue-i18n は、Vue.jsアプリケーションで多言語対応(国際化)を実現するための主要なライブラリです。vue-i18n はVue公式チームが開発するVue専用のソリューションであり、Vueのリアクティブシステムと緊密に統合されています。一方、i18next-vue は、フレームワーク非依存の国際化エンジンである i18next のVue向けバインディングで、i18nextの豊富なエコシステムと柔軟性を活用できます。どちらも翻訳キーの管理、動的言語切り替え、フォールバック処理などの基本機能を提供しますが、設計思想や拡張性、学習コストに明確な違いがあります。
Vue.jsアプリケーションで多言語対応を実装するには、i18next-vueとvue-i18nが主要な選択肢です。どちらも成熟した国際化機能を提供しますが、設計思想や統合方法、拡張性に明確な違いがあります。この記事では、実際の開発現場で直面する技術的課題を中心に、両者の違いを深く掘り下げます。
**vue-i18n**はVue.js公式チームによって開発・メンテナンスされているVue専用のi18nライブラリです。Vueのリアクティブシステムと密接に連携し、コンポーネント内での翻訳キーの使用や動的メッセージの更新を自然にサポートします。
// vue-i18n: プラグイン設定
import { createApp } from 'vue';
import { createI18n } from 'vue-i18n';
const i18n = createI18n({
locale: 'ja',
messages: {
ja: { hello: 'こんにちは' },
en: { hello: 'Hello' }
}
});
const app = createApp(App);
app.use(i18n);
app.mount('#app');
**i18next-vue**は、広く使われている国際化フレームワーク i18next のVue向けバインディングです。i18next自体はフレームワーク非依存で、React、Angular、Vanilla JSなど多くの環境で利用されています。そのため、既にi18nextを使っているプロジェクトや、複数のフロントエンド技術を横断して共通のi18n戦略を取りたい場合に適しています。
// i18next-vue: 設定
import { createApp } from 'vue';
import i18next from 'i18next';
import I18NextVue from 'i18next-vue';
i18next.init({
lng: 'ja',
resources: {
ja: { translation: { hello: 'こんにちは' } },
en: { translation: { hello: 'Hello' } }
}
});
const app = createApp(App);
app.use(I18NextVue, { i18next });
app.mount('#app');
**vue-i18n**は $t グローバルメソッドや <i18n-t> コンポーネントを提供し、テンプレート内で直感的に翻訳キーを参照できます。Composition APIを使う場合は useI18n() フックを利用します。
<!-- vue-i18n: Options API -->
<template>
<p>{{ $t('hello') }}</p>
</template>
<script>
export default {
// ...
}
</script>
<!-- vue-i18n: Composition API -->
<template>
<p>{{ t('hello') }}</p>
</template>
<script setup>
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
</script>
**i18next-vue**は $t メソッドをグローバルプロパティとして注入しますが、Composition API向けの専用フックは提供していません。代わりに、i18next のグローバルインスタンスを直接使うか、カスタムフックを作成する必要があります。
<!-- i18next-vue -->
<template>
<p>{{ $t('hello') }}</p>
</template>
<script setup>
// Composition APIでの使用例(カスタムフックなし)
import i18next from 'i18next';
const t = i18next.t;
</script>
大規模アプリでは、翻訳リソースをコード分割して初期バンドルサイズを抑えることが重要です。
**vue-i18n**は defineAsyncComponent や動的インポートと組み合わせて、言語リソースを非同期で読み込むことができます。また、@intlify/unplugin-vue-i18n を使うことで、ビルド時にJSON/YAMLファイルをモジュールとして取り込めます。
// vue-i18n: 非同期言語切り替え
async function changeLocale(locale) {
if (!i18n.global.availableLocales.includes(locale)) {
const messages = await import(`./locales/${locale}.json`);
i18n.global.setLocaleMessage(locale, messages.default);
}
i18n.global.locale = locale;
}
**i18next-vue**はi18nextのバックエンドプラグイン(例:i18next-http-backend)を使って、必要に応じて翻訳ファイルをHTTP経由で取得できます。これにより、初期ロード時に全言語を含める必要がなくなります。
// i18next-vue: HTTP経由での遅延読み込み
import HttpApi from 'i18next-http-backend';
i18next.use(HttpApi).init({
lng: 'ja',
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json'
}
});
開発中に翻訳キーの存在確認やフォールバック動作を検証したい場面は多いです。
**vue-i18n**は開発モードで未登録のキーをコンソールに警告出力する機能があり、またVue Devtools拡張機能と連携して現在のロケールや翻訳状態を可視化できます。
// vue.config.jsでDevtoolsサポートを有効化
module.exports = {
chainWebpack: config => {
config.plugin('define').tap(args => {
args[0]['__VUE_I18N_FULL_INSTALL__'] = JSON.stringify(true);
return args;
});
}
};
**i18next-vue**はi18next本体のデバッグモードを有効にすることで、キーの解決過程やフォールバック動作を詳細にトレースできます。
i18next.init({
debug: true, // 開発時のみtrueに
// ...
});
ユーザーが言語を変更した際に、画面全体を再レンダリングせずに翻訳文だけを更新できるかどうかはUXに直結します。
**vue-i18n**はVueのリアクティブシステムと完全に統合されており、i18n.global.locale を変更すると、すべての $t() 呼び出しが自動的に再評価され、DOMが更新されます。
// 言語切り替え(リアクティブ更新)
i18n.global.locale = 'en'; // これだけで全コンポーネントが更新
**i18next-vue**も同様に、i18next.changeLanguage() を呼び出すと、内部でイベントを発行し、バインディングがVueコンポーネントの再レンダリングをトリガーします。
// 言語切り替え
i18next.changeLanguage('en');
ただし、カスタムフックや手動で i18next.t を呼び出している場合、再レンダリングが発生しない可能性があるため注意が必要です。
**vue-i18n**はVueに特化しているため、他のVueプラグイン(例:Vue Routerとの統合)との連携がスムーズです。たとえば、URLのパスに基づいて言語を自動設定するといった高度なユースケースにも対応しやすいです。
**i18next-vue**はi18nextの豊富なエコシステム(300以上のプラグイン)を活用できます。例えば、翻訳管理サービス(Locize、Phraseなど)との統合、複数名前空間の扱い、複雑なフォールバックチェーンなど、企業レベルの要件を満たす柔軟性があります。
| 観点 | vue-i18n | i18next-vue |
|---|---|---|
| Vueとの統合度 | ⭐⭐⭐⭐⭐(公式サポート) | ⭐⭐⭐(サードパーティバインディング) |
| 学習コスト | 低(Vue開発者向けに最適化) | 中(i18nextの概念を理解必要) |
| 拡張性 | Vue内では十分 | 非常に高い(i18nextエコシステム) |
| マルチフレームワーク対応 | ❌ | ✅(React/Angularなどと共通化可能) |
| 遅延読み込み | ビルド時/動的インポート対応 | HTTPバックエンド対応 |
vue-i18nを選ぶべきケース:Vue専用プロジェクトで、シンプルで直感的なAPIと公式サポートを重視する場合。特に中小規模のアプリや、Vue生態系に深く依存するプロジェクトに最適です。
i18next-vueを選ぶべきケース:既にi18nextを使っている、または複数のフロントエンド技術を横断して国際化戦略を統一したい場合。また、高度な翻訳管理やエンタープライズ向け機能(例:翻訳メモリ、機械翻訳連携)が必要な場合にも有利です。
どちらも安定しており、新しいプロジェクトで使って問題ありません。最終的には、チームの技術スタックや長期的なメンテナンス戦略に合わせて選ぶのが賢明です。
vue-i18n は、Vue.js 専用のプロジェクトでシンプルかつ直感的な国際化を実現したい場合に最適です。Vue 公式チームによるサポートを受けられ、Composition API や Vue Devtools との統合もスムーズです。中小規模のアプリケーションや、Vue 生態系に深く依存するプロジェクトでは、開発体験と保守性の面で大きなメリットがあります。
i18next-vue は、すでに i18next を他のプロジェクト(React、Angular など)で使用している場合や、複数のフロントエンド技術間で国際化戦略を統一したい場合に最適です。i18next の豊富なプラグインエコシステム(HTTP バックエンド、翻訳管理サービス連携など)を活用したいエンタープライズ向けプロジェクトにも向いています。ただし、Vue 専用の機能やツールとの統合はやや限定的です。
Internationalization plugin for Vue.js
vue-i18n(.runtime).global(.prod).js:
<script src="..."> in the browser. Exposes the VueI18n global<script src="...">vue-i18n.global.js is the "full" build that includes both the compiler and the runtime so it supports compiling locale messages on the flyvue-i18n.runtime.global.js contains only the runtime and requires locale messages to be pre-compiled during a build step@intlify/shared@intlify/message-compiler@intlify/core*.prod.js files for productionvue-i18n(.runtime).esm-browser(.prod).js:
<script type="module">)vue-i18n(.runtime).esm-bundler.js:
webpack, rollup and parcelprocess.env.NODE_ENV guards (must be replaced by bundler)@intlify/core-base, @intlify/message-compiler)
esm-bundler builds and will in turn import their dependencies (e.g. @intlify/message-compiler imports @intlify/shared)vue-i18n.runtime.esm-bundler.js (default) is runtime only, and requires all locale messages to be pre-compiled. This is the default entry for bundlers (via module field in package.json) because when using a bundler templates are typically pre-compiled (e.g. in *.json files)vue-i18n.esm-bundler.js: includes the runtime compiler. Use this if you are using a bundler but still want locale messages compilation (e.g. templates via inline JavaScript strings)vue-i18n.cjs(.prod).js:
require()target: 'node' and properly externalize vue-i18n, this is the build that will be loadedprocess.env.NODE_ENVvue-i18n(.runtime).node.mjs:
importprocess.env.NODE_ENVvue-i18n(.runtime).mjs
vue-i18n.runtime.node.mjs: is runtime onlyvue-i18n.node.mjs: includes the runtime compilerNOTE: ES Modules will be the future of the Node.js module system. The
vue-i18n.cjs(.prod).jswill be deprecated in the future. We recommend you would usevue-i18n(.runtime).node.mjs. 9.3+
The esm-bundler builds now exposes global feature flags that can be overwritten at compile time:
__VUE_I18N_FULL_INSTALL__ (enable/disable, in addition to vue-i18n APIs, components and directives all fully support installation: true)__VUE_I18N_LEGACY_API__ (enable/disable vue-i18n legacy style APIs support, default: true)__INTLIFY_DROP_MESSAGE_COMPILER__ (enable/disable whether to tree-shake message compiler when we will be bundling)The build will work without configuring these flags, however it is strongly recommended to properly configure them in order to get proper tree shaking in the final bundle. To configure these flags:
define optionNote: the replacement value must be boolean literals and cannot be strings, otherwise the bundler/minifier will not be able to properly evaluate the conditions.