# General Translation Knowledge Base: vue-i18n から gt-vue へ移行するにはどうすればよいですか？
URL: https://generaltranslation.com/ja/kb/migrate-from-vue-i18n.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: gt-vue を vue-i18n と併用する形でインストールし、アクティブなロケールを同期したうえで、コンポーネントを1つずつ $t キーから `<T>` と useGT 内のインライン文言へ移行します。移行した文言は、General Translation がテンプレート構造を文脈として翻訳し、チームはダッシュボードでその翻訳を修正できます。未移行のコンポーネントでは、レビュー済みの vue-i18n メッセージが引き続き使用されます。
Category: 国際化
Last updated: 2026-11-11
Authors: Kevin Wu
Published: 2026-11-11

vue-i18n は、言語ごとのメッセージファイルに記述した翻訳をレンダリングします。一方、gt-vue はテンプレート内にインラインで記述した文言をレンダリングし、その翻訳は General Translation が [`npx gt translate`](/docs/cli/reference/commands/translate) で生成します。移行作業では、両方のプラグインを同じアプリ内で動作させたまま、コンポーネント単位で `$t('key')` による参照を、そのキーが指す原文に置き換えていきます。

## vue-i18n の API は gt-vue のどの API に対応しますか？

| vue-i18n                                           | gt-vue                                                                                                                                                                                 |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `createI18n({ locale, fallbackLocale, messages })` | [`createGT`](/docs/vue/reference/functions/create-gt)`({ defaultLocale, loadTranslations })` (ロケールは `gt.config.json` で指定)                                                              |
| `app.use(i18n)`                                    | `app.use(gt)`                                                                                                                                                                          |
| テンプレート内の `$t('key')`                               | 文言を [`<T>`](/docs/vue/reference/components/t) で囲むか、[`useGT`](/docs/vue/reference/composables/use-gt) から取得した文字列を使用                                                                      |
| `<script setup>` 内の `t('key')`                     | `const gt = useGT()` で取得し、`computed` 内で `gt('Inbox')` を呼び出す                                                                                                                            |
| `{name}` による名前付き補間                                 | [`<T>`](/docs/vue/reference/components/t) 内で [`<Var>`](/docs/vue/reference/components/var) を使用                                                                                         |
| スロット付きの `<i18n-t keypath="...">`                   | 実際のマークアップを [`<T>`](/docs/vue/reference/components/t) でラップする                                                                                                                            |
| `'no apples \| one apple \| {count} apples'`       | `#zero`、`#singular`、`#plural` スロットを使った [`<Plural>`](/docs/vue/reference/components/plural)                                                                                             |
| 名前付きフォーマットを使った `n()` と `d()`                       | [`<Num>`](/docs/vue/reference/components/num)、[`<Currency>`](/docs/vue/reference/components/currency)、[`<DateTime>`](/docs/vue/reference/components/datetime) (`Intl` オプションはインラインで指定)  |
| `locale.value = 'fr'`                              | [`useSetLocale`](/docs/vue/reference/composables/use-set-locale)`()('fr')`。現在のロケールは [`useLocale`](/docs/vue/reference/composables/use-locale) で取得                                      |
| `setLocaleMessage` による遅延読み込み                       | `loadTranslations(locale)` オプションで各ロケールを読み込み、キャッシュ                                                                                                                                      |
| `fallbackLocale`                                   | `defaultLocale`。翻訳がない場合は原文がレンダリングされる                                                                                                                                                   |

メッセージキー、SFC の `<i18n>` カスタムブロック、リンクメッセージ (`@:key`) は、すべてインラインの文言に置き換えます。各メッセージのテキストはそれをレンダリングするテンプレートに移し、リンクメッセージは参照先の内容をそのまま書き出してください。

## ステップ 1: vue-i18n と併用する形で gt-vue をインストールする

gt-vue (現在 0.x) は Vue 3.3 以降に対応しています。[Vue クイックスタート](/docs/vue/quickstart)の手順に従ってください。概要は次のとおりです。

1. `gt-vue` をインストールし、`gt` CLI を開発依存関係としてインストールします。

2. vue-i18n の設定と同じソースロケールおよびターゲットロケールを指定し、`src/_gt/[locale].json` などの出力パスを設定した `gt.config.json` を作成します。

3. `loadTranslations` 関数を追加し、vue-i18n と並べてプラグインをインストールします。

   ```ts title="src/main.ts"
   import { createApp } from 'vue';
   import { createGT, type LoadTranslations } from 'gt-vue';
   import App from './App.vue';
   import i18n from './i18n'; // 既存の createI18n インスタンス

   const loadTranslations: LoadTranslations = async (locale) => {
     try {
       return (await import(`./_gt/${locale}.json`)).default;
     } catch {
       return {};
     }
   };

   createApp(App)
     .use(i18n)
     .use(createGT({ defaultLocale: 'en', loadTranslations }))
     .mount('#app');
   ```

4. [`npx gt login`](/docs/cli/reference/commands/login) でサインインし、プロジェクトIDを設定します。

gt-vue では Vite プラグインは不要です。[`npx gt translate`](/docs/cli/reference/commands/translate) を実行すると、CLI が `.vue` ファイル内の [`<T>`](/docs/vue/reference/components/t) と [`useGT`](/docs/vue/reference/composables/use-gt) をスキャンします。

## ステップ 2: アクティブなロケールを1つに統一する

gt-vue を言語切り替え機能として使用し、そのロケールを vue-i18n にコピーして、未移行のコンポーネントも同じロケールに追従するようにします。

```vue title="src/App.vue"
<script setup lang="ts">
import { watchEffect } from 'vue';
import { useI18n } from 'vue-i18n';
import { useLocale } from 'gt-vue';

const gtLocale = useLocale();
const { locale } = useI18n({ useScope: 'global' });

watchEffect(() => {
  locale.value = gtLocale.value;
});
</script>
```

言語メニューを、[`useSetLocale`](/docs/vue/reference/composables/use-set-locale) を呼び出すコントロールに置き換えます。[`createGT`](/docs/vue/reference/functions/create-gt) を使用している場合、ロケールを切り替えると新しいロケールの翻訳が読み込まれ、ページをリロードせずに再レンダリングされます。また、選択したロケールは gt-vue によって `generaltranslation.locale` クッキーに保存されます。

## ステップ 3: コンポーネントを1つずつ移行する

メッセージファイルにあるソース言語のテキストを、テンプレートにコピーします。変更前:

```json title="src/locales/en.json"
{
  "greeting": "Hello, {name}!",
  "unread": "You have no messages | You have {count} message | You have {count} messages",
  "inbox": "Inbox"
}
```

```vue title="src/components/InboxHeader.vue"
<script setup lang="ts">
import { useI18n } from 'vue-i18n';
defineProps<{ name: string; count: number }>();
const { t } = useI18n();
</script>

<template>
  <h1>{{ t('inbox') }}</h1>
  <p>{{ t('greeting', { name }) }}</p>
  <p>{{ t('unread', count) }}</p>
</template>
```

変更後:

```vue title="src/components/InboxHeader.vue"
<script setup lang="ts">
import { computed } from 'vue';
import { T, Var, Num, Plural, useGT } from 'gt-vue';
defineProps<{ name: string; count: number }>();

const gt = useGT();
const title = computed(() => gt('Inbox')); // computed を使うことで、ロケールの変更にリアクティブに追従します
</script>

<template>
  <h1>{{ title }}</h1>
  <T>
    <p>Hello, <Var>{{ name }}</Var>!</p>
    <p>
      <Plural :n="count">
        <template #zero>You have no messages</template>
        <template #singular>You have <Num :value="count" /> message</template>
        <template #plural>You have <Num :value="count" /> messages</template>
      </Plural>
    </p>
  </T>
</template>
```

General Translation は、`singular` と `plural` のスロットから、ロシア語の `few` や `many` など各対象言語に必要な形を生成し、[`<Plural>`](/docs/vue/reference/components/plural) が `Intl.PluralRules` を使ってその中から 1 つを選択します。一方、vue-i18n のパイプ構文では、これらの言語に対してカスタムの複数形処理ルールを用意する必要があります。`zero` スロットを使えば、受信トレイが空のときの文言をそのまま維持できます。タイトルやプレースホルダーなどの静的な文字列には [`useGT`](/docs/vue/reference/composables/use-gt) を使用し、ランタイムの値を含む文はすべて [`<Var>`](/docs/vue/reference/components/var) と組み合わせて [`<T>`](/docs/vue/reference/components/t) で囲んでください。コンポーネントを一通り移行するたびに [`npx gt translate`](/docs/cli/reference/commands/translate) を実行し、すべてのロケールを確認しましょう。

## 既存の翻訳はどうなりますか？

まだ移行していないコンポーネントでは、レビュー済みの vue-i18n メッセージが引き続きレンダリングされるため、段階的に移行しても変わるのは手を加えた画面だけです。gt-vue はメッセージキーではなくソースコンテンツで翻訳を識別します。そのため、[`<T>`](/docs/vue/reference/components/t) や [`useGT`](/docs/vue/reference/composables/use-gt) に移した文言には、[`npx gt translate`](/docs/cli/reference/commands/translate) が周囲のテンプレートを文脈として新しい翻訳を生成します。[コンテキストグループ](/docs/platform/dashboard/guides/defining-context-for-translations)の用語集とカスタムプロンプトを使えば、用語やトーンの一貫性を保てます。生成後の文言は、レビュー担当者が[ダッシュボード](/docs/platform/dashboard/guides/reviewing-translations)で自由に修正できます。

## ステップ 4: vue-i18n を削除する

`$t(`、`useI18n`、`<i18n-t`、`vue-i18n` を検索しても何もヒットしなくなったら、`createI18n` のセットアップ、メッセージファイル、ロケールの同期処理、`vue-i18n` の依存関係を削除します。続いて、[`npx gt translate`](/docs/cli/reference/commands/translate) をビルドまたは [CI](/kb/translations-in-ci) に組み込み、新しく追加したテキストがリリースごとに翻訳された状態で公開されるようにします。

## よくある質問

### gt-vue は Nuxt に対応していますか？

gt-vue には Nuxt モジュールがなく、`@nuxtjs/i18n` のようなローカライズされたルート、hreflang タグ、ブラウザの言語検出といった機能も提供していません。ただし、CLI は Nuxt の `pages/` および `layouts/` フォルダをスキャンします。また、リクエストごとにプラグインを 1 つ作成すれば、[`createGT`](/docs/vue/reference/functions/create-gt) を使ってサーバー側でレンダリングできます。

### gt-vue はメッセージキーをサポートしていますか？

いいえ。gt-vue が翻訳するのは、[`<T>`](/docs/vue/reference/components/t) や [`useGT`](/docs/vue/reference/composables/use-gt) 内にインラインで記述されたテキストです。キーを中心としたワークフローを採用している場合は、引き続き vue-i18n を使用してください。

### コンポーネントを1つずつ移行できますか？

はい。アクティブなロケールを共有していれば、両方のプラグインを同じアプリ内で併用できます。vue-i18n を使用している箇所がすべてなくなったら、vue-i18n を削除してください。

### gt-vue は無料ですか？

gt-vue は MIT ライセンスで提供されており、アカウントがなくてもバンドルされた翻訳をレンダリングできます。General Translation による翻訳の生成は[従量課金制](https://generaltranslation.com/pricing)です。

## 要点

* gt-vue を vue-i18n と併用し、言語の切り替えは gt-vue で行います。移行が完了するまでは、gt-vue のロケールを vue-i18n にコピーしてください。
* `$t` のキーをインラインのテキストに置き換えます。テンプレートには [`<T>`](/docs/vue/reference/components/t) と [`<Var>`](/docs/vue/reference/components/var) を、パイプ形式の複数形には [`<Plural>`](/docs/vue/reference/components/plural) の `singular` スロットと `plural` スロットを、script 内の静的な文字列には `computed` 内で [`useGT`](/docs/vue/reference/composables/use-gt) を使用します。
* 未移行のコンポーネントでは、レビュー済みの vue-i18n メッセージがそのまま使われます。移行したテキストはテンプレートを文脈として翻訳され、ダッシュボードでレビューされます。メッセージキーや `@nuxtjs/i18n` のルーティングがアプリの中核を担っている場合は、vue-i18n を使い続けてください。
* vue-i18n を参照する箇所がなくなったら削除し、CI で [`npx gt translate`](/docs/cli/reference/commands/translate) を実行します。

## Related questions

- [General Translation と vue-i18n：どちらを使うべきか](https://generaltranslation.com/ja/kb/general-translation-vs-vue-i18n.mdx): General Translation を使うと、Vue チームはテンプレートに翻訳元の文言を直接記述し、CLI で翻訳を生成できます。gt-vue プラグインは、そのコンテンツをロケール対応の複数形や数値書式設定でレンダリングします。キーで管理する原文ファイルの保守をなくしたいなら General Translation が適しています。一方、Nuxt の i18n モジュールと確立されたカタログのワークフローを利用しているチームには、引き続き vue-i18n が適しています。
- [Vue アプリを翻訳するにはどうすればよいですか？](https://generaltranslation.com/ja/kb/translate-vue-app.mdx): Vue アプリを翻訳するには、各テンプレート文字列をアクティブな言語に応じて参照される形にし、すべての対象言語に翻訳します。General Translation の gt-vue プラグインは `<T>` コンポーネントでラップされたコンテンツを翻訳し、npx gt translate は対象言語ごとに 1 つのカタログを書き出します。
- [デプロイのたびに翻訳を最新の状態に保つにはどうすればよいですか？](https://generaltranslation.com/ja/kb/translations-in-ci.mdx): 本番環境のビルド前に、翻訳をパイプラインのステップとして毎回実行します。こうすることで、新しいテキストは追加されたデプロイと同時に翻訳済みの状態でリリースされます。General Translation の gt CLI では、CI シークレットとして保存したプロジェクトの APIキーとプロジェクトIDを使い、npx gt translate でこれを実現します。

## Previous and next questions

- Previous question: [react-i18next から gt-react へ移行するにはどうすればよいですか？](https://generaltranslation.com/ja/kb/migrate-from-react-i18next.mdx)
- Next question: [AIコーディングエージェントと翻訳パイプライン：ローカライゼーションの自動化にはどちらを使うべきか](https://generaltranslation.com/ja/kb/ai-coding-agent-vs-translation-pipeline.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/ja/kb/sitemap.md) for every article.
