# General Translation Knowledge Base: Payload CMS でコンテンツを翻訳するにはどうすればよいですか？
URL: https://generaltranslation.com/ja/kb/translate-payload-content.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Payload の設定に localization を追加し、各フィールドで localized を true に設定します。これで Payload はロケールごとに 1 つの値を保存できるようになりますが、値自体は自動では入力されません。General Translation の gt-payload プラグインを使うと「Translate」ボタンが追加され、各対象ロケールの値を書き込めます。ドラフトが有効な場合はドラフトとして、そうでない場合は直接書き込みます。公開は一切行いません。
Category: ワークフローツール
Last updated: 2026-10-28
Authors: General Translation Team
Published: 2026-10-28

Payload CMS は翻訳をフィールド単位で保存します。設定に `localization` ブロックを追加すると、`localized: true` を指定した各フィールドが同じドキュメント内でロケールごとに 1 つの値を持つようになり、フロントエンドは `locale` パラメータで言語を指定して取得します。ただし、Payload はこれらの値を生成しません。しかも値の入力は意外と手間がかかります。Lexical のリッチテキスト (Payload のデフォルトエディタ) にはリンク、マーク、埋め込みブロックが含まれ、配列やブロックの中にはローカライズ対象のフィールドが入れ子になっています。スラッグ、リレーション、アップロードは変更せずに維持する必要があり、編集者が翻訳に加えた修正が次回の更新で上書きされないようにしなければなりません。

## Payload における翻訳の保存方法

Payload 3 では、ローカライゼーションは Payload のコア設定に組み込まれています ([Payload のローカライゼーションに関するドキュメント](https://payloadcms.com/docs/configuration/localization)) 。ロケールは一度定義するだけで済みます：

```ts title="src/payload.config.ts"
import { buildConfig } from 'payload';

export default buildConfig({
  // ... 既存の設定
  localization: {
    locales: ['en', 'es', 'fr'], // または code、label、rtl、fallbackLocale を持つオブジェクト
    defaultLocale: 'en',
    fallback: true, // デフォルト値：値が存在しない場合はデフォルトロケールにフォールバックする
  },
});
```

次に、翻訳対象の各フィールドを指定します。`localized: true` は配列やブロックを含む、名前を持つあらゆるフィールドに設定でき、ローカライズされたコンテナ内にネストされたフィールドはロケールごとのセットになります。Payload の警告によると、すでにデータが入っているフィールドの `localized` を変更すると、そのフィールドの既存データは失われます。コンテンツを読み込む前に設定を決めておきましょう。

どの API もロケールを指定できます。REST では `?locale=es` や `?fallback-locale=none` を使用し、GraphQL では `locale` 引数と `fallbackLocale` 引数を指定します。Local API でも同じオプションを指定できます。

```ts
// スペイン語の値を取得。スペイン語の値がないフィールドは英語にフォールバックする
const page = await payload.findByID({ collection: 'pages', id, locale: 'es' });

// スペイン語の値のみを取得。未翻訳のフィールドは空になる
const strict = await payload.findByID({ collection: 'pages', id, locale: 'es', fallbackLocale: false });

// すべてのロケールを一括取得: all.title は { en: 'Pricing', es: 'Precios' } になる
const all = await payload.findByID({ collection: 'pages', id, locale: 'all' });
```

Payload 3.92 のテストアプリで、英語とスペイン語のタイトルしか持たないページに `fr` を指定したところ、デフォルトでは英語のタイトルが返され、`fallbackLocale: false` を指定すると空のタイトルが返されました。このデフォルトの挙動は押さえておくべきです。未翻訳のロケールはエラーにならず、翻訳元の言語が黙って返されるからです。

## Payload のコンテンツを翻訳する方法

Payload の公式プラグインには SEO、Redirects、Search、Import/Export がありますが、コンテンツを翻訳するものはありません ([Payload plugins](https://payloadcms.com/docs/plugins/overview)) 。主な選択肢は次のとおりです。

| アプローチ                                                                                                            | 得意なこと                                                                                           | 翻訳を Payload に反映する方法                                                                | 自分で対応すること                                                             |
| ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| 編集者が各ロケールを手入力する                                                                                                  | 翻訳者が管理画面で各フィールドを確認しながら作業できる                                                                     | 管理画面のロケールを切り替えて各値を入力する                                                             | すべての翻訳作業と、翻訳元を編集するたびに変更されたフィールドを探す作業                                  |
| Payload の [Import/Export plugin](https://payloadcms.com/docs/plugins/import-export) と翻訳者または翻訳管理システム (TMS) の組み合わせ | ファイルベースで翻訳する人向けに、ロケールを CSV または JSON にエクスポートできる                                                  | 翻訳済みファイルを対象ロケールにインポートする                                                            | エクスポートからインポートまでの過程でリッチテキスト、ブロック、行 ID を壊さないようにすること、および編集後の再エクスポート      |
| AI API (OpenAI API、Claude API) を使うスクリプト                                                                          | 1 回の実行で多数のドキュメントを翻訳でき、トーンや用語をプロンプトで指定できる                                                        | スクリプトが `payload.update({ locale })` で書き込む                                          | ネストされたフィールドと Lexical JSON の走査、各文字列への文脈の付与、用語の統一、レビュー、再実行              |
| [Lingo.dev](https://lingo.dev/guides/payload) (`@lingo.dev/payloadcms`)                                          | 翻訳元を保存すると、ローカライズ対象のテキストとリッチテキストを自動で翻訳する                                                         | ホスト型サービスが各ロケールを公開済みまたはドラフトとして書き込む                                                   | Lingo.dev のエンタープライズプランの契約、APIキーを持つ Payload のサービスユーザー、Lexical エディターの使用 |
| General Translation (`gt-payload`)                                                                               | ローカライズ対象の `text`、`textarea`、Lexical の `richText` (ネストされたブロックを含む) を、プロジェクトの用語集とカスタムプロンプトに沿って翻訳する | ドキュメントごとの **Translate** ボタン、またはサイト全体を対象とした 1 回の実行で各ロケールを書き込む (ドラフトが有効な場合はドラフトとして保存)  | 翻訳元の編集後に実行を開始すること、各ロケールのレビュー、ドラフトの公開                                   |

ドキュメント数が少なく、言語ごとに翻訳者がいる場合は手入力で十分です。翻訳会社や TMS がすでに翻訳を担当し、ファイルベースで作業している場合は Import/Export が適しています。単発のバッチを翻訳し、人がレビューするなら AI API スクリプトを使いましょう。ドキュメントにリッチテキストやブロックが含まれ、更新頻度が高く、アプリやドキュメントと用語を統一したい場合は General Translation が最適です。 (2 つのサービスの比較については [General Translation vs. Lingo.dev](/kb/general-translation-vs-lingo-dev) を参照してください。)

## gt-payload で Payload のコンテンツを翻訳する

General Translation の `gt-payload` プラグイン (MITライセンス、バージョン 0.1.2) を使用するには、`localization` を設定済みの Payload 3.90.0 以降、Next.js 15.2.9 以降、React 19.0.1 以降、および1つ以上のローカライズ対象フィールドが必要です。

1. `npm install gt-payload` でインストールします。

2. プラグインを設定に追加します。ロケールとローカライズ対象フィールドは Payload から自動的に読み取られるため、通常はオプションを指定する必要はありません。

   ```ts title="src/payload.config.ts"
   import { buildConfig } from 'payload';
   import { gtPlugin } from 'gt-payload';

   export default buildConfig({
     // ... 既存の設定
     localization: {
       locales: ['en', 'es', 'fr'],
       defaultLocale: 'en',
     },
     plugins: [gtPlugin()],
   });
   ```

3. Payload を実行するサーバーで、`GT_PROJECT_ID` と、**All** 権限を持つ[プロジェクトAPIキー](/docs/platform/dashboard/reference/api-keys#create-project-keys)を `GT_API_KEY` として設定します。キーは絶対にクライアントコードに公開しないでください。

4. `npx payload generate:importmap` を実行して、管理画面がプラグインのコンポーネントを読み込めるようにします。PostgreSQL または SQLite を使用している場合は、プラグインが追加する2つのコレクションのためにマイグレーションを作成して適用します (`npx payload migrate:create` を実行してから `npx payload migrate` を実行) 。

5. 保存済みのドキュメントを開いて **Translate** を選択し、ターゲットロケールを選んでから **Translate into …** を選択します。すべてをまとめて翻訳する場合は、管理ナビゲーションの **Translations** を開きます。

Payload 3.92.1 のテストアプリでは、プラグインのドキュメントコントロール、**Translations** ビュー、`gt-translation-runs` および `gt-translation-locks` コレクションがインポートマップと生成された型に追加され、`next build` も成功しました。プラグインのエンドポイントは、Payload にサインインしていないユーザーからのリクエストを拒否します。詳しい手順は [Payload クイックスタート](/docs/integrations/payload/quickstart)を参照してください。

## 翻訳の実行で行われること

プラグインはデフォルトロケールを翻訳元として使用し、各ドキュメントのローカライズ対象テキストを General Translation のプロジェクトに送信します。送信されたテキストは、Payload 上の識別子 (`collection/id`、またはグローバルのスラッグ) の下に表示されます。翻訳対象は、ローカライズされた `text` フィールド (`hasMany` リストを含む) 、`textarea` フィールド、Lexical の `richText` です。グループ、タブ、配列、ブロック、リッチテキストブロック内にあるものも対象になります。リッチテキストでは、マーク、リンク、アップロード、ブロックがそのまま保持されます。マークアップを翻訳元と対応付けられない文字列は、壊れた状態で書き込まれることはなく、スキップされて報告されます。

スラッグフィールド、読み取り専用・非表示・仮想フィールド、URL・パス・メールアドレスのように見える `text` の値、リレーション、アップロード、日付、数値、ID には手を加えません。SKU などのフィールドを翻訳対象から除外するには、そのフィールドに `custom: { gt: { translate: false } }` を設定します。翻訳がフィールドの `maxLength` を超える場合、プラグインはより短い翻訳を要求します。それでも収まらない場合に限り、単語の区切りで切り詰めて省略記号を付けます。 ([サポート対象のコンテンツ](/docs/integrations/payload/reference/supported-content)を参照してください。) 

翻訳結果は、同じドキュメントの各対象ロケールに書き込まれます。[ドラフト](https://payloadcms.com/docs/versions/drafts)が有効なコレクションとグローバルではドラフトとして作成され、それ以外は直接保存されます。プラグインが公開を行うことはありません。実行状況は Payload 内に保存されるため、タブを閉じても処理は継続されます。次に管理画面を開いたときに再開されるほか、`jobs.autoRun` が設定されていれば Payload の[ジョブキュー](https://payloadcms.com/docs/jobs-queue/overview)によって完了します。一部のドキュメントやロケールで失敗しても、他の結果が取り消されることはありません。

## レビュー、公開、編集内容の保持

各ロケールは Payload のエディターでレビューし、通常の Payload の権限で公開してください。プラグインのコントロールは、サインイン中のユーザーのアクセスルールに従います。編集者が Payload 上で翻訳を修正した場合は、**Translations** ドロワーで **Save local edits before translating** をオンにする (デフォルトではオフ) か、**Save local edits** を選択してください。こうしておけば、以降の実行でも General Translation はその表現を維持します。保存すると Payload の値が正となり、そのドキュメントについて General Translation が保持している内容は置き換えられます ([翻訳の管理](/docs/integrations/payload/guides/managing-translations)を参照) 。

翻訳の品質は文脈で決まります。プロジェクトに[コンテキストグループ](/docs/platform/dashboard/guides/defining-context-for-translations)を割り当てると、その用語集とカスタムプロンプトがすべての Payload の実行に適用されます。これにより、製品名やプラン名が CMS のページでもアプリ内と同じように翻訳されます。フックや定期実行ジョブなど、独自のコードから翻訳するには、`gt-payload` の [`translateDocument`](/docs/integrations/payload/reference/api#translate-document) または `translateSite` を呼び出します。利用料金は [General Translation の料金体系](https://generaltranslation.com/pricing)に基づいて請求されます。

言語ごとの URL や `hreflang` など、多言語サイトに必要なその他の要素については、[ウェブサイトを多言語化するには？](/kb/make-website-multilingual)を参照してください。他の CMS での同様の手順については、[Sanity](/kb/translate-sanity-content) と [Storyblok](/kb/translate-storyblok-content) の記事で解説しています。

## 重要なポイント

* Payload 3 は翻訳をフィールドごとに保存します。設定に `localization` を追加して `localized: true` を指定し、`locale` と `fallback-locale` を使って読み取ります。
* デフォルトの `fallback: true` では、未翻訳のロケールには原文が表示されます。言語へのリンクを設置する前に、翻訳がどこまで済んでいるかを確認してください。
* Payload には公式の翻訳プラグインがありません。Import/Export プラグインを使えば、ロケールを CSV または JSON 形式で書き出して翻訳者に渡せます。
* General Translation の `gt-payload` は、`gtPlugin()`、**Translate** ボタン、サイト全体を対象とする **Translations** ページを追加します。ローカライズされた text、textarea、Lexical のリッチテキストを翻訳し、ドラフトが有効な場合は各ロケールをドラフトとして保存します。公開が行われることはありません。
* **Save local edits before translating** を有効にしておくと、Payload 上で行った編集が以降の実行でも上書きされずに残ります。

## Related questions

- [Sanity でコンテンツを翻訳するには？](https://generaltranslation.com/ja/kb/translate-sanity-content.mdx): 各言語を個別のドキュメントとして保存するか、各フィールドにロケールごとの値として保存し、翻訳元をすべての対象ロケールに翻訳します。General Translation の gt-sanity プラグインは Sanity Studio に Translate アクションを追加します。デフォルトでは各翻訳が下書きとしてインポートされるため、レビューしてから公開できます。
- [Storyblok でコンテンツを翻訳するにはどうすればよいですか？](https://generaltranslation.com/ja/kb/translate-storyblok-content.mdx): Storyblok では、スペースに対象言語を追加し、翻訳可能な各フィールドに言語ごとの値を設定します。General Translation の Storyblok インテグレーションを使うと、ダッシュボードの「同期して適用」でこれらの値が下書きとして入力されるので、Storyblok 上でレビューして公開できます。
- [ウェブサイトを多言語化するにはどうすればよいですか？](https://generaltranslation.com/ja/kb/make-website-multilingual.mdx): 翻訳をどこで管理するか（プロキシ、CMSプラグイン、サイトビルダー、または自前のコード）を選び、Googleの推奨どおり言語ごとに専用のURLを用意します。ページ全体に加えてタイトルとメタディスクリプションも翻訳し、hreflangで各言語版を関連付けます。また、訪問者を自動でリダイレクトするのではなく、言語切り替え機能を設置しましょう。
- [翻訳をレビュー・編集するにはどうすればよいですか？](https://generaltranslation.com/ja/kb/review-translations.mdx): 各翻訳を翻訳元や他のロケールと見比べ、不自然な箇所を修正します。General Translation では、ダッシュボードの翻訳ページで翻訳を編集し、ラベルとコメントでレビューの進捗を管理します。編集内容は、AIエージェントである Locadex による次回の翻訳実行でプルリクエストに取り込まれます。
- [General Translation と Lingo.dev の比較：どちらを使うべきか](https://generaltranslation.com/ja/kb/general-translation-vs-lingo-dev.mdx): Lingo.dev は設定可能な翻訳エンジンを中核とし、CLI、React、GitHub 向けのツールを通じてそれらを利用します。General Translation はローカライゼーションプラットフォームで、ライブラリ、コードの文脈、共有用語、全プランで使える ダッシュボード でのレビュー、さらにコードの国際化まで担う Locadex を備えています。言語ペアごとにモデルを制御したいなら Lingo.dev を選びましょう。

## Previous and next questions

- Previous question: [Next.js Pages Router アプリに i18n を追加するには？](https://generaltranslation.com/ja/kb/add-i18n-to-nextjs-pages-router.mdx)
- Next question: [POファイルとPOTファイルはどのように翻訳すればよいですか？](https://generaltranslation.com/ja/kb/translate-po-files.mdx)

## Sitemap

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