# General Translation Knowledge Base: next-intl から gt-next に移行するには？
URL: https://generaltranslation.com/ja/kb/migrate-from-next-intl.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: next-intl のプラグイン、ミドルウェア、プロバイダーを gt-next のものに置き換え、ロケールプレフィックスの設定を揃えたうえで、messages/en.json を gt-next の辞書として読み込めば、既存の ICU メッセージと翻訳はそのまま動作します。next-intl のルーティングを削除する前にローカライズされたパス名をマッピングし、その後ルートごとに文言を `<T>` へインラインで移していきます。
Category: 国際化
Last updated: 2026-11-11
Authors: Kevin Wu
Published: 2026-11-11

next-intl と gt-next はどちらも、ロケールプレフィックス付きのルートとサーバーコンポーネントを使って Next.js App Router アプリをローカライズするため、アプリの構造はほとんど変わりません。next-intl のメッセージはすでに ICU MessageFormat で書かれており、これは gt-next の辞書と同じ形式です。そのため、`messages/en.json` と翻訳済みのカタログをそのまま残してライブラリを切り替え、その後は自分のペースで文言を [`<T>`](/docs/react/reference/components/t) へインラインで移していけます。

カタログ自体は問題なく機能していて、翻訳の作成に時間がかかることだけが課題であれば、移行は不要かもしれません。next-intl を使い続ける場合でも、`gt` CLI でそのカタログをインプレースで翻訳できます。 ([next-intl と gt-next の比較](/kb/next-intl-vs-gt-next)を参照してください。)

## next-intl の API は gt-next のどの API に対応しますか？

| next-intl                                                                          | gt-next                                                                                                                                                                                                                                                  |
| ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `defineRouting({ locales, defaultLocale })`                                        | `gt.config.json` の `defaultLocale` と `locales`                                                                                                                                                                                                           |
| `next.config.ts` の `createNextIntlPlugin()`                                        | `gt-next/config` の [`withGTConfig`](/docs/react/nextjs/config)                                                                                                                                                                                           |
| `proxy.ts` の `createMiddleware(routing)`                                           | `gt-next/middleware` の [`createNextMiddleware`](/docs/react/nextjs/reference/functions/create-next-middleware)                                                                                                                                           |
| `localePrefix: 'as-needed'` / `'always'`                                           | `prefixDefaultLocale: false` (デフォルト) / `true`                                                                                                                                                                                                            |
| `i18n/request.ts` の `getRequestConfig`                                             | `next/root-params` を読み取るルートの `getLocale.ts` と `dictionary` オプション                                                                                                                                                                                         |
| `NextIntlClientProvider`                                                           | `app/[locale]/layout.tsx` 内の [`GTProvider`](/docs/react/reference/components/gt-provider)                                                                                                                                                                |
| `useTranslations('ns')`                                                            | `gt-next` の [`useTranslations`](/docs/react/reference/hooks/use-translations)`('ns')`                                                                                                                                                                    |
| `await getTranslations('ns')`                                                      | `gt-next/server` の `await` [`getTranslations`](/docs/react/nextjs/reference/functions/get-translations)`('ns')`                                                                                                                                          |
| `t.rich` と `t.markup`                                                              | 実際の JSX をラップする [`<T>`](/docs/react/reference/components/t)                                                                                                                                                                                               |
| `useFormatter` / `getFormatter`                                                    | [`<Num>`](/docs/react/reference/components/num)、[`<Currency>`](/docs/react/reference/components/currency)、[`<DateTime>`](/docs/react/reference/components/datetime)、[`<RelativeTime>`](/docs/react/reference/components/relative-time)、またはメッセージ内の ICU 引数 |
| [`useLocale` / `getLocale`](https://next-intl.dev/docs/usage/configuration#locale) | [`useLocale`](/docs/react/reference/hooks/use-locale) / [`getLocale`](/docs/react/nextjs/reference/functions/get-locale)                                                                                                                                 |
| `setRequestLocale(locale)`                                                         | `getLocale.ts` があればページとレイアウトでは不要。ルートハンドラーと画像ルートでは [`registerLocale`](/docs/react/nextjs/reference/functions/register-locale) を使用                                                                                                                         |
| `createNavigation` の `Link`                                                        | `gt-next/link` の [`Link`](/docs/react/nextjs/link)                                                                                                                                                                                                       |
| `useRouter` / `getPathname` / `redirect`                                           | Next.js 標準の API に [`useLocalizeHref`](/docs/react/nextjs/reference/hooks/use-localize-href) または [`getLocalizeHref`](/docs/react/nextjs/reference/functions/get-localize-href) を組み合わせて使用                                                                  |
| `NEXT_LOCALE` クッキー                                                                 | `generaltranslation.locale` (`headersAndCookies.localeCookieName` で名前を変更可能)                                                                                                                                                                              |

## ステップ 1: プラグインを置き換え、メッセージはそのまま残す

`gt-next` と `gt` CLI をインストールし、`gt.config.json` に使用する言語を列挙します。`withGTConfig` が既存の翻訳元カタログを参照するように設定し、URL 構造を next-intl に合わせます:

```ts title="next.config.ts"
import type { NextConfig } from 'next';
import { withGTConfig } from 'gt-next/config';

const nextConfig: NextConfig = {};

export default withGTConfig(nextConfig, {
  dictionary: './messages/en.json',
  prefixDefaultLocale: true, // next-intl のデフォルト（localePrefix: 'always'）
  headersAndCookies: { localeCookieName: 'NEXT_LOCALE' }, // 再訪したユーザーの言語設定を保持する
});
```

`localePrefix: 'as-needed'` を使用していた場合は、`prefixDefaultLocale` を省略してください。gt-next の `<Link>` はルーティングオプションを `withGTConfig` から読み取るため、ミドルウェアだけでなく `withGTConfig` にも設定してください。

この例では、`/de/about` のような標準的なロケールプレフィックスを扱います。`defineRouting` の呼び出しでルートをカスタマイズしている場合は、Step 2 で削除する前に、それぞれのカスタマイズを移行しておいてください：

* **ローカライズされたパス名** (`pathnames`、例：`/de/ueber-uns`) ：gt-next の [`pathConfig`](/docs/react/nextjs/reference/functions/create-next-middleware#path-config) オプションで個別にマッピングします。このオプションも、共通のパスとロケールごとのローカライズ済みパスという同じ構造を取ります。
* **カスタムプレフィックス、ドメインベースのルーティング、または `localePrefix: 'never'`：** gt-next には直接対応する機能がありません。next-intl のルーティングを削除する前に新しい URL を決め、旧 URL からの恒久的なリダイレクトを追加してください。

レビュー済みの翻訳を引き続き配信するには、プロジェクトルートに `loadDictionary.ts` ファイルを追加します。このファイルは gt-next が自動的に検出します：

```ts title="loadDictionary.ts"
export default async function loadDictionary(locale: string) {
  try {
    return (await import(`./messages/${locale}.json`)).default;
  } catch {
    return {}; // カタログのない新しいロケールでは General Translation の翻訳を使用
  }
}
```

これらのファイル内のエントリが優先されます。カタログにないキーについては、General Translation の翻訳がレンダリングされます。`gt.config.json` の `files` にこれらのカタログがすでに記載されている場合は、そのエントリを削除してください。gt-next はこれらを辞書として読み込むようになったため、各文字列の翻訳の管理元は 1 か所にまとめる必要があります。

## ステップ 2: ミドルウェア、レイアウト、リクエスト設定を置き換える

`proxy.ts`(Next.js 15 以前では `middleware.ts`)内の next-intl のミドルウェアを置き換えます。

```ts title="proxy.ts"
import { createNextMiddleware } from 'gt-next/middleware';

export default createNextMiddleware();

export const config = {
  matcher: ['/((?!api|static|.*\\..*|_next).*)'],
};
```

ルートのマッピングが済んだら、`i18n/request.ts` と `i18n/routing.ts` を削除します。代わりにプロジェクトのルートに `getLocale.ts` を追加すると、`setRequestLocale` を使わなくてもページやレイアウトを静的にレンダリングできます：

```ts title="getLocale.ts"
import { locale } from 'next/root-params';

export default async function getLocale() {
  return await locale();
}
```

`next/root-params` には Next.js 15.5 以降が必要です。15.2 〜 15.4 をお使いの場合は、[ミドルウェアガイド](/docs/react/nextjs/app-router-middleware#root-locale)を参照してください。次に、ロケールレイアウト内のプロバイダーを置き換えます。

```tsx title="app/[locale]/layout.tsx"
import { GTProvider, getLocales } from 'gt-next';
import { getLocale } from 'gt-next/server';

export function generateStaticParams() {
  return getLocales().map((locale) => ({ locale }));
}

export default async function LocaleLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang={await getLocale()}>
      <body>
        <GTProvider>{children}</GTProvider>
      </body>
    </html>
  );
}
```

デフォルトでは、gt-next はサポート対象外のロケールセグメントに対して `defaultLocale` にフォールバックします。next-intl の `hasLocale` チェックと同じように 404 を返すには、[`isLocaleSupported`](/docs/react/nextjs/reference/functions/is-locale-supported) でセグメントを判定し、`notFound()` を呼び出します。

## ステップ 3: インポート文を変更する

カタログを辞書として読み込めば、ほとんどのコンポーネントはインポート行を書き換えるだけで済みます。

```tsx
// 変更前
import { useTranslations } from 'next-intl';
import { getTranslations } from 'next-intl/server';
import { Link } from '@/i18n/navigation';

// 変更後
import { useTranslations } from 'gt-next';
import { getTranslations } from 'gt-next/server';
import Link from 'gt-next/link';
```

`t('heading')`、名前空間、`{name}` プレースホルダー、ICU の `plural` および `select` メッセージは、`generateMetadata` 内も含めてそのまま動作します。修正が必要なパターンは次の3つです。

* **`t.rich` と `t.markup`。** gt-next の [`t()`](/docs/react/reference/hooks/use-translations) は文字列を返します。リッチテキストは、実際の要素を使って [`<T>`](/docs/react/reference/components/t) 内にインラインで記述してください。
* **配列を使う `t.raw`。** gt-next には `t.raw` がなく、辞書内の配列はメッセージとそのオプションとしてのみ読み取られます。リストはネストしたオブジェクトに再構成し、[`t.obj()`](/docs/react/guides/translating-with-dictionaries#objects) で読み取るか、キーを1つずつ読み取ってください。
* **存在しないキー。** next-intl はエラーをログに出力してフォールバックをレンダリングしますが、gt-next は例外をスローします。そのため、カタログからキーを削除する前に、そのキーが使われていないか検索してください。

次に [`npx gt validate`](/docs/cli/reference/commands/validate) を実行して ICU として無効なエントリがないか確認し、[`npx gt translate --dictionary ./messages/en.json`](/docs/cli/reference/commands/translate) を実行して、カタログに不足しているキーと新しいロケールの翻訳を生成します。CLI が辞書を自動検出するのは、プロジェクトルートまたは `src/` に `dictionary.json`、`.ts`、`.js` という名前で配置されている場合に限られます。そのため、カタログを使い続ける間は、ローカルでも CI でも両方のコマンドに `--dictionary ./messages/en.json` を指定してください。

```bash
npx gt validate --dictionary ./messages/en.json
npx gt translate --dictionary ./messages/en.json
```

## ステップ 4: ルートごとにコピーをインラインへ移行する

キーはそのまま動作し続けるため、ここで終えても構いません。コピーを、それをレンダリングする JSX のすぐそばに置きたい場合は、まず `t.rich` メッセージから着手し、ルート単位で [`<T>`](/docs/react/reference/components/t) に移行してください：

```tsx
// 変更前: "terms": "By continuing you accept the <link>terms</link>."
t.rich('terms', { link: (chunks) => <a href="/terms">{chunks}</a> });

// 変更後
<T>
  By continuing you accept the <a href="/terms">terms</a>.
</T>
```

非同期のサーバーコンポーネントでは、プレーンな文字列に [`getGT`](/docs/react/nextjs/reference/functions/get-gt) を使用します。インラインに移動したテキストも、同じ [`npx gt translate`](/docs/cli/reference/commands/translate) コマンドで新しい翻訳が生成されます。その際、周囲の JSX が文脈として利用されます。レビュー担当者は [ダッシュボード](/docs/platform/dashboard/guides/reviewing-translations) で翻訳を修正でき、[コンテキストグループ](/docs/platform/dashboard/guides/defining-context-for-translations) の用語集によって用語の一貫性が保たれます。どこからも参照されなくなったキーは、順次カタログから削除してください。

## ステップ 5: next-intl を削除する

`next-intl` を検索して何もヒットしなくなったら、依存関係と `createNextIntlPlugin` を削除し、すべてのロケールで本番環境ビルドをテストします。次に、[`npx gt translate`](/docs/cli/reference/commands/translate) をビルドまたは [CI](/kb/translations-in-ci) に組み込み、新しい文言が翻訳済みの状態でリリースされるようにします。カタログを残した場合は、`--dictionary ./messages/en.json` を指定してください。

## よくある質問

### URLは変わりますか？

next-intlの設定に合わせておけば、標準的なロケールプレフィックスについては変わりません。`localePrefix: 'as-needed'`はgt-nextのデフォルトに、`'always'`は`prefixDefaultLocale: true`に相当します。gt-nextでも`app/[locale]`セグメントを使用します。ローカライズされたパス名には、明示的な`pathConfig`マッピングが必要です。また、カスタムプレフィックスやドメインベースのルーティングにはgt-next側に直接対応する機能がありません。そのため、これらのURLはリダイレクトで対応し、next-intlのルーティングを削除する前にすべてのルートをテストしてください。

### 既存の翻訳は失われますか？

いいえ。next-intl のカタログを [`loadDictionary`](/docs/react/reference/functions/load-dictionary) で読み込めば、これまでどおりレンダリングされます。General Translation が翻訳するのは、カタログに存在しないキーと、後から [`<T>`](/docs/react/reference/components/t) 内にインラインで移したテキストだけです。

### gt-next は静的レンダリングに対応していますか？

はい。ルートに `getLocale.ts` を作成し、`generateStaticParams` を追加してください。 (詳しくは[静的サイト生成](/docs/react/nextjs/app-router-static-site-generation)を参照してください。)

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

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

## 重要なポイント

* next-intl のプラグイン、ミドルウェア、リクエスト設定、プロバイダーを、それぞれ `withGTConfig`、[`createNextMiddleware`](/docs/react/nextjs/reference/functions/create-next-middleware)、`getLocale.ts`、[`GTProvider`](/docs/react/reference/components/gt-provider) に置き換えます。
* `messages/en.json` は gt-next の辞書としてそのまま使い、翻訳済みのカタログも [`loadDictionary`](/docs/react/reference/functions/load-dictionary) 経由で引き続き利用できます。ICU メッセージは変更不要です。
* `localePrefix` に合わせて `prefixDefaultLocale` を設定し、`NEXT_LOCALE` クッキーを維持すれば、標準的なロケール URL と保存済みの設定をそのまま引き継げます。ローカライズされたパス名は、next-intl のルーティングを削除する前に `pathConfig` でマッピングしてください。
* `t.rich` は [`<T>`](/docs/react/reference/components/t) に書き換え、その他のテキストはルートごとに順次インラインへ移行します。

## Related questions

- [next-intl の代替：gt-next と next-intl の比較](https://generaltranslation.com/ja/kb/next-intl-vs-gt-next.mdx): next-intl は、言語ごとのメッセージカタログに用意した翻訳をレンダリングします。gt-next も翻訳をレンダリングしますが、それに加えて General Translation が JSX にインラインで記述したテキストから翻訳を生成します。どちらも MIT ライセンスで、App Router とサーバーコンポーネントに対応しています。既存の next-intl のカタログが問題なく機能しているなら、移行せずにそのまま使い続けながら、General Translation で翻訳できます。
- [Next.js App Router アプリに i18n を追加するには？](https://generaltranslation.com/ja/kb/add-i18n-to-nextjs.mdx): まず gt init を実行して、対応する App Router プロジェクトに General Translation を設定します。次にソースコンテンツをマークし、翻訳を生成して、言語の切り替えが機能することを確認します。gt-next はテキストを翻訳の文脈とともに JSX 内に保持し、生成、レビュー、継続的な更新は CLI、ダッシュボード エディター、Locadex が担います。このガイドでは、ローカルファイルを明示的に使うセットアップ方法も紹介します。
- [多言語対応の Next.js アプリで SEO を設定するには？](https://generaltranslation.com/ja/kb/multilingual-nextjs-seo.mdx): 各言語に /en/about や /es/about のようなプレフィックス付きの URL を割り当て、公開している言語ごとに html lang、自己参照のカノニカル、x-default を含む hreflang の代替リンク、翻訳済みのタイトルと説明文、サイトマップのエントリを出力します。未公開のバージョンには noindex を指定します。General Translation の gt-next は各言語を専用の URL にルーティングし、getGT でタイトルを翻訳します。
- [言語リダイレクトと SEO：URL、クッキー、Accept-Language のどれを使うべきか](https://generaltranslation.com/ja/kb/locale-routing-seo.mdx): Googlebot は Accept-Language ヘッダーを送信せず、クロールの大半を米国の IP アドレスから行います。そのため、インデックスさせたいすべてのページの言語は URL で決めましょう。保存済みのクッキーの選択、次いで Accept-Language を使うのは、/ のような中立的なルートのリダイレクト先を決める場合だけにとどめ、その際は一時的な 302 または 307 を使います。
- [デプロイのたびに翻訳を最新の状態に保つにはどうすればよいですか？](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: [シート数ではなく使用量に応じて課金する翻訳ツールはどれですか？](https://generaltranslation.com/ja/kb/translation-pricing-without-seat-fees.mdx)
- Next question: [react-i18next から gt-react へ移行するにはどうすればよいですか？](https://generaltranslation.com/ja/kb/migrate-from-react-i18next.mdx)

## Sitemap

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