# General Translation Knowledge Base: General Translation と nestjs-i18n：どちらを使うべきか？
URL: https://generaltranslation.com/ja/kb/general-translation-vs-nestjs-i18n.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: nestjs-i18n は NestJS アプリでリクエストごとに言語を解決し、言語別の JSON または YAML カタログからメッセージをレンダリングしますが、翻訳そのものは行いません。General Translation の CLI はそれらのカタログを翻訳し、gt-node ライブラリは実行時にしか存在しないコンテンツを翻訳します。そのため、nestjs-i18n はそのままに General Translation を追加できます。
Category: 国際化
Last updated: 2026-10-16
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-16

nestjs-i18n は NestJS 向けのオープンソース i18n モジュールです。クエリ文字列、ヘッダー、クッキー、または `Accept-Language` からリクエストごとの言語を判定し、`I18nContext` または `I18nService` がその言語のメッセージをカタログから返します。翻訳をレンダリングすることはできても、翻訳を生成することはできません。そのため、各言語のカタログは開発者自身や翻訳者、あるいは外部サービスが作成し、常に最新の状態に保つ必要があります。General Translation は、この欠けた部分を 2 つの方法で補います。CLI で nestjs-i18n のカタログを翻訳し、`gt-node` ライブラリで実行時にしか存在しないコンテンツを翻訳します。

## nestjs-i18n の強み

* **Nest 専用の設計。** `I18nModule.forRoot()` を 1 回呼び出すだけで、[`I18nContext` 用の `@I18n()` パラメータデコレーターと、サービス内で使える `I18nContext.current()`](https://nestjs-i18n.com/quick-start) が利用できます。HTTP、GraphQL、gRPC、WebSockets のいずれでも動作します。
* **言語リゾルバー。** [`QueryResolver`、`HeaderResolver`、`CookieResolver`、`AcceptLanguageResolver`](https://nestjs-i18n.com/concepts/resolver) は指定した順に実行されます。GraphQL と gRPC にはそれぞれ専用のリゾルバーが用意されており、独自のリゾルバーを作成することもできます。
* **シンプルなカタログ。** 言語ごとのフォルダー (`src/i18n/en/`、`src/i18n/es/`) に [JSON または YAML ファイル](https://nestjs-i18n.com/concepts/loader)を置くだけで、各ファイル名がそのまま名前空間 (`inbox.title`) になります。開発時にはライブリロードも使えます。
* **複数形と補間。** `{name}` プレースホルダー、他のキーを参照する `$t()`、そして `Intl.PluralRules` によって選択される [`zero`、`one`、`two`、`few`、`many`、`other` キーを持つ複数形オブジェクト](https://nestjs-i18n.com/guides/plurals)を利用できます。[10.8.0 で追加された](https://github.com/toonvanstrijp/nestjs-i18n/releases/tag/v10.8.0)オプトインの `useICU` 設定を有効にすると、ICU MessageFormat でメッセージを書式設定することもできます。
* **型安全性。** [`typesOutputPath` によって `I18nTranslations` 型と `I18nPath` 型が生成される](https://nestjs-i18n.com/guides/type-safety)ため、キーの入力ミスはコンパイルエラーになります。また、`nestjs-i18n check` コマンドを使えば、キーが欠けている言語がある場合にエラーで終了します。
* **バリデーションメッセージ。** `I18nValidationPipe`、`I18nValidationExceptionFilter`、`i18nValidationMessage()` を使って、[DTO の class-validator エラーを翻訳](https://nestjs-i18n.com/guides/dto_validation/global-validation)できます。

ライセンスは MIT で、[バージョン 10.8.5 では Node.js 22 以降が必要です](https://github.com/toonvanstrijp/nestjs-i18n/blob/v10.8.5/package.json)。

## nestjs-i18n が開発者任せにしていること

以下は、複数形を含む英語の受信トレイ用カタログです。

```json title="src/i18n/en/inbox.json"
{
  "title": "Inbox",
  "unread": {
    "one": "You have {count} unread message.",
    "other": "You have {count} unread messages."
  }
}
```

スペイン語フォルダーにはファイルを翻訳したコピーが置かれており、コントローラーは `i18n.t('inbox.unread', { args: { count } })` を返します。ドイツ語フォルダーはありません。nestjs-i18n 10.8.5 を使った最小構成の Nest 11 アプリにリクエストを送ると、次のようになります:

```text title="Output"
?lang=es&count=3  "Tienes 3 mensajes sin leer."
?lang=de&count=3  "You have 3 unread messages."
```

ドイツ語はカタログがまだ翻訳されていないため、英語にフォールバックします。言語検出は機能しますが、欠けているテキストまでは補えません。これこそ nestjs-i18n が開発者に任せている作業、つまりカタログを作成し、英語が変わるたびに最新の状態に保つことです。

## General TranslationとNestJSアプリの連携

General TranslationのCLIは、nestjs-i18nのカタログを既存の場所に置いたまま翻訳します。`json`エントリで言語フォルダを指定してください。

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": [
    "es",
    "de"
  ],
  "files": {
    "json": {
      "include": [
        "src/i18n/[locale]/*.json"
      ]
    }
  }
}
```

[`npx gt translate`](/docs/cli/reference/commands/translate) は `src/i18n/en/inbox.json` を読み込み、すべてのキーを保持したまま `src/i18n/es/inbox.json` と `src/i18n/de/inbox.json` を書き出します。CI で実行すると、変更のないエントリには以前の翻訳がそのまま再利用されます。生成されたカタログは、nestjs-i18n が既存のローダーで読み込みます。

この例では、`one` と `other` の形式を持つ英語、スペイン語、ドイツ語のメッセージを使用しています。生成されたメッセージをカウント 1 と 3 でプレビューし、リリース前に `nestjs-i18n check -p src/i18n` を実行して、不足しているキーがないか確認してください。

チームメイトの投稿やデータベースのレコードなど、実行時にしか存在しないコンテンツには、General Translation の [`gt-node`](/docs/node/quickstart) を使用します。一度初期化しておけば、あとは [`tx`](/docs/node/reference/functions/tx) を呼び出す際に、nestjs-i18n が解決した言語を [`withGT`](/docs/node/reference/functions/with-gt) に渡すだけです：

```ts title="src/main.ts"
import { NestFactory } from '@nestjs/core';
import { initializeGT } from 'gt-node';
import { AppModule } from './app.module';

// 環境変数から GT_PROJECT_ID と GT_API_KEY（実行時翻訳が有効なプロジェクトキー）を読み込みます。
initializeGT({ defaultLocale: 'en', locales: ['en', 'es', 'de'] });

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

```ts title="src/posts.controller.ts"
import { Controller, Get, Param } from '@nestjs/common';
import { I18n, I18nContext } from 'nestjs-i18n';
import { tx, withGT } from 'gt-node';
import { PostsService } from './posts.service';

@Controller('posts')
export class PostsController {
  constructor(private readonly posts: PostsService) {}

  @Get(':id')
  async findOne(@Param('id') id: string, @I18n() i18n: I18nContext) {
    return withGT(i18n.lang, async () => {
      const post = await this.posts.findOne(id);
      return { ...post, body: await tx(post.body, { $context: 'A post written by a user' }) };
    });
  }
}
```

これで、どちらのツールも既存の nestjs-i18n リゾルバーが選択した言語を使用するようになります。`?lang=es` が `Accept-Language: de` より優先される場合、カタログのメッセージも翻訳された投稿もスペイン語になります。固定のインターフェース文言にはカタログを、ユーザーが作成したコンテンツには [`tx`](/docs/node/reference/functions/tx) を使用してください。

型付きキー、カタログ参照、バリデーションメッセージには引き続き nestjs-i18n を使用します。General Translation は、翻訳の生成、共有の用語集とカスタムプロンプト、[ダッシュボードでのレビュー](/docs/platform/dashboard/guides/reviewing-translations)を担います。固定の文言には上記のカタログワークフローを、動的コンテンツには `tx` を使用してください。

## nestjs-i18n と General Translation の比較一覧

| 機能           | nestjs-i18n                                            | General Translation                                                                                                |
| ------------ | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| 役割           | リクエストの言語を解決し、カタログからメッセージをレンダリングする                      | カタログを翻訳し、動的コンテンツも実行時に翻訳する                                                                                          |
| コンテンツの翻訳     | なし                                                     | あり ([`npx gt translate`](/docs/cli/reference/commands/translate) と [`tx`](/docs/node/reference/functions/tx) を使用)  |
| 言語検出         | クエリ、ヘッダー、クッキー、`Accept-Language`、GraphQL、gRPC、カスタムリゾルバー | [`withGT`](/docs/node/reference/functions/with-gt) を通じて、解決済みの同じ言語を使用                                               |
| 複数形          | 言語ごとのカテゴリキーを使用し、`Intl.PluralRules` で選択                 | ソースファイルにある複数形キーを翻訳                                                                                                 |
| 型安全性         | キー型の生成と欠落キーのチェック                                       | カタログのキーを維持するため、同じ生成型をそのまま使用可能                                                                                      |
| バリデーションメッセージ | class-validator とのインテグレーション                            | これらのメッセージの元となるカタログを翻訳                                                                                              |
| 費用           | 無料 (MIT ライセンス)                                         | [従量課金制](https://generaltranslation.com/pricing)                                                                    |

## 使い分けの指針

リゾルバー、型付きキー、バリデーションとのインテグレーションについては、引き続き nestjs-i18n を使用してください。英語のテキストが変更されるたびに CI でカタログを翻訳したい場合や、API が返すユーザーコンテンツやデータベースのコンテンツをその場で翻訳する必要がある場合は、General Translation を追加しましょう。既存のコントローラーはこれまでと同じキーをそのまま使用でき、General Translation がそれらのキーに対応するテキストを常に最新の状態に保ちます。

## 両方を併用する

1. nestjs-i18n とそのフォルダはそのまま残します。
2. カタログのパスを指定した `gt.config.json` を追加し、`GT_API_KEY` と `GT_PROJECT_ID` を設定します ([CLI の設定](/docs/cli/guides/configuring#credentials)を参照) 。
3. 既存の翻訳を [`npx gt upload`](/docs/cli/reference/commands/upload) でアップロードし、CI で [`npx gt translate`](/docs/cli/reference/commands/translate) を実行します。
4. 以降にローカル翻訳を編集した場合は、再生成する前に [`npx gt save-local`](/docs/cli/reference/commands/save-local) を実行します。実行時翻訳が必要な箇所には `gt-node` を追加します。

## 重要なポイント

* nestjs-i18n は NestJS での言語検出、型付きキー、複数形、バリデーションメッセージを処理しますが、すべての言語のカタログは、各言語の複数形も含めてすべて自分で作成する必要があります。
* General Translation の CLI は nestjs-i18n の JSON カタログをインプレースで翻訳し、`gt-node` は同じリクエスト言語を使って動的コンテンツを翻訳します。
* 両者は組み合わせて使うのがおすすめです。nestjs-i18n がレンダリングを、General Translation が翻訳を担います。

## Related questions

- [General Translation vs. i18next、react-intl、next-intl：どのi18nライブラリを使うべきか？](https://generaltranslation.com/ja/kb/general-translation-vs-i18n-libraries.mdx): i18next、react-intl、next-intlなどのオープンソースライブラリ自体は、翻訳を一切行いません。これらが行うのは、あなた自身や翻訳者、あるいは別のサービスが作成し、言語ごとのカタログファイルに用意した翻訳を表示することだけです。General Translationのライブラリも同じくオープンソースで同じ役割を果たしますが、General Translationはさらに、コードを文脈として活用しながら翻訳そのものも行います。
- [TMS（Smartling、Lokalise、Phrase、Crowdin、Transifex）ではなく General Translation を使う理由](https://generaltranslation.com/ja/kb/general-translation-vs-tms.mdx): Smartling、Lokalise、Phrase、Crowdin、Transifex などの翻訳管理システム（TMS）は翻訳者間の作業を取りまとめますが、文字列の抽出、送信、翻訳待ち、プロダクトへの再組み込みは依然としてエンジニアの仕事です。General Translation はコード内のコンテンツを文脈ごと翻訳し、リリースのたびに全言語をまとめて提供します。ロックインのないオープンソースのライブラリ上で動作します。
- [i18nは自前で構築すべきか、General Translationを使うべきか](https://generaltranslation.com/ja/kb/general-translation-vs-in-house-i18n.mdx): 自前のi18n（言語ごとの辞書と小さな t() ヘルパー）は、対応言語が1〜2つで文言も少ないうちは十分に機能します。しかしアプリが成長するにつれて、複数形規則、フォールバック、ファイルの同期を自分で作り直すことになり、そのうえ翻訳そのものも用意しなければなりません。General Translationのオープンソースライブラリがレンダリングを担い、General Translationがコードから翻訳を生成・更新します。
- [General Translation と Symfony Translation の比較：どちらを使うべきか](https://generaltranslation.com/ja/kb/general-translation-vs-symfony-translation.mdx): Symfony Translation は PHP と Twig でメッセージをレンダリングします。General Translation は CI で YAML カタログを翻訳し、翻訳元の変更に合わせて常に最新の状態に保つほか、レビュー担当者が翻訳を編集できる ダッシュボード も提供します。Symfony のレンダリングはそのままに、リリースワークフローに自動翻訳を組み込めます。
- [翻訳ファイルなしで i18n はできますか？](https://generaltranslation.com/ja/kb/i18n-without-translation-files.mdx): はい。gt-react または gt-next を使えば、コンテンツは `<T>` コンポーネントで囲んだままコンポーネント内にインラインで記述でき、翻訳はビルド時に出力として生成されます。そのため、キーやロケールごとの JSON ファイルを作成したり、同期を保ったりする必要はありません。

## Previous and next questions

- Previous question: [General Translation と Mobility：どちらを使うべきか？](https://generaltranslation.com/ja/kb/general-translation-vs-mobility.mdx)
- Next question: [General Translation と Paraglide JS：どちらを使うべきか](https://generaltranslation.com/ja/kb/general-translation-vs-paraglide.mdx)

## Sitemap

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