jpskill.com
🛠️ 開発・MCP コミュニティ

api-cms-payload

Payload CMS v3は、TypeScriptで構築されたヘッドレスCMSで、コードファーストなコレクション定義、柔軟なAPI、管理画面、データベース連携機能を備え、コンテンツ管理を効率化するSkill。

📜 元の英語説明(参考)

Payload CMS v3 — TypeScript-native headless CMS with code-first collections, hooks, access control, Local/REST/GraphQL APIs, admin panel, and database adapter pattern

🇯🇵 日本人クリエイター向け解説

一言でいうと

Payload CMS v3は、TypeScriptで構築されたヘッドレスCMSで、コードファーストなコレクション定義、柔軟なAPI、管理画面、データベース連携機能を備え、コンテンツ管理を効率化するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o api-cms-payload.zip https://jpskill.com/download/10229.zip && unzip -o api-cms-payload.zip && rm api-cms-payload.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10229.zip -OutFile "$d\api-cms-payload.zip"; Expand-Archive "$d\api-cms-payload.zip" -DestinationPath $d -Force; ri "$d\api-cms-payload.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して api-cms-payload.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → api-cms-payload フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Payload CMS のパターン

クイックガイド: TypeScript を用いたコードファーストのコンテンツ管理には Payload を使用してください。コレクションとグローバルを、型付きフィールド、フック、およびアクセス制御関数を持つ設定オブジェクトとして定義します。サーバーサイドの操作には、ローカル API (payload.find, payload.create) を優先してください。常に設定から TypeScript の型を生成してください。データベースアダプター(Postgres または MongoDB)を使用し、認証情報をハードコードしないでください。アクセス制御関数は、認証されたユーザーを含む { req } を受け取ります。フックはドキュメントのライフサイクルレベル(beforeChange、afterChange など)で実行され、意図的な場合を除き、リクエストをブロックする副作用を持ってはなりません。


<critical_requirements>

重要: この Skill を使用する前に

すべてのコードは CLAUDE.md のプロジェクト規約に従う必要があります (kebab-case、名前付きエクスポート、インポート順序、import type、名前付き定数)

(すべてのコレクションでアクセス制御を定義する必要があります — オープンなコレクションはセキュリティリスクです)

(サーバーサイドのデータ操作には、ローカル API (payload.find, payload.create) を使用する必要があります — レイテンシがゼロで、完全に型付けされています)

(スキーマを変更するたびに、payload generate:types で TypeScript の型を生成する必要があります)

(JSX/React コンポーネントのインポートを Payload 設定ファイルから除外する必要があります — 設定と UI の関心を分離してください)

(ユーザーの代わりにローカル API を呼び出す場合は、overrideAccess: false を使用する必要があります — デフォルトは true で、すべてのアクセス制御をバイパスします)

</critical_requirements>


自動検出: Payload, payload, payloadcms, @payloadcms, buildConfig, CollectionConfig, GlobalConfig, payload.config.ts, payload.find, payload.create, payload.update, payload.delete, payload.findByID, lexicalEditor, richText, beforeChange, afterChange, afterRead, beforeValidate, access control payload, upload collection, imageSizes, versions drafts

使用する場面:

  • データベースアダプター、コレクション、およびグローバルを使用して payload.config.ts を構成する
  • 型付きフィールド(text、richText、relationship、blocks、array、group、upload、select)を使用してコレクションスキーマを定義する
  • アクセス制御関数(ロールベース、所有権ベース、フィールドレベル)を実装する
  • コレクションフック(beforeChange、afterChange、beforeRead、afterRead、beforeValidate、beforeDelete、afterDelete)を作成する
  • ローカル API、REST API、または GraphQL を介してデータをクエリする
  • ログイン、ロール、および JWT を使用して認証コレクションを設定する
  • 画像サイズと MIME タイプ制限を使用してアップロード/メディアを構成する
  • コレクションまたはグローバルでバージョンとドラフトを有効にする
  • 管理パネルをカスタマイズする(グループ、非表示コレクション、カスタムコンポーネント)

カバーされる主要なパターン:

  • buildConfig、データベースアダプター、エディター設定を使用した payload.config.ts のセットアップ
  • コレクション設定: slug、fields、hooks、access、auth、upload、versions、admin
  • フィールドタイプ: text、richText、relationship、upload、blocks、array、group、select、tabs、checkbox、date、number、email、code、json、point、radio、textarea、row、collapsible
  • アクセス制御: コレクションレベルおよびフィールドレベル、ブール値または Where クエリを返す
  • フック: beforeChange、afterChange、beforeRead、afterRead、beforeValidate、beforeDelete、afterDelete、beforeOperation、afterOperation
  • ローカル API: payload.find, payload.findByID, payload.create, payload.update, payload.delete, payload.count
  • REST API: /api/{collection-slug} で自動生成されたエンドポイント
  • グローバル: サイト設定、ナビゲーション、フッター用のシングルトンドキュメント
  • 認証コレクション: auth: true、roles、login strategies
  • アップロード: imageSizes、mimeTypes、メディアコレクション
  • バージョンとドラフト: versions: { drafts: true }
  • TypeScript の型生成

使用しない場面:

  • 単純なキーと値のストレージ(データベースを直接使用する)
  • コンテンツ編集のニーズがない静的サイト生成
  • 管理パネルなしで REST API のみが必要なアプリケーション(プレーンな API フレームワークを使用する)
  • クライアントサイドのデータフェッチパターン(Payload のローカル API はサーバー専用です)

詳細なリソース:

  • 意思決定フレームワークとアンチパターンについては、reference.md を参照してください。

コアセットアップとコレクション:

  • examples/core.md — 設定のセットアップ、コレクションの定義、フィールドタイプ、アクセス制御、フック

高度なパターン:

  • examples/advanced.md — グローバル、バージョン/ドラフト、アップロード/メディア、認証コレクション、ローカル API、REST API

<philosophy>

哲学

Payload は、スキーマをコードとして扱う TypeScript ネイティブのヘッドレス CMS です。GUI をクリックしてコンテンツモデルを構築する代わりに、コレクションとグローバルを TypeScript 設定オブジェクトとして定義します。Payload は、管理パネル、REST API、GraphQL API、および完全に型付けされたローカル API を設定から自動生成します。

コア原則:

  1. Config-as-code -- コレクション、グローバル、フィールド、フック、およびアクセス制御はすべて TypeScript で定義されます。スキーマは、他のコードと同様に、バージョン管理され、レビュー可能で、デプロイ可能です。
  2. 1 つの設定から 3 つの API -- すべてのコレクションは、ローカル API(サーバー専用、レイテンシゼロ)、REST API (/api/{slug})、および GraphQL API を自動的に取得します。ローカル API は、サーバーサイド操作の主要なインターフェースです。
  3. アクセス制御は必須 -- すべてのコレクションには明示的な access 関数が必要です。デフォルトでは、Payload は認証されていないユーザーへのアクセスを拒否しますが、誰が何ができるかを定義する必要があります。アクセス関数は、ブール値または結果をスコープするための Where クエリを返すことができます。
  4. 副作用のためのフック -- ライフサイクルフック(beforeChange、afterChange など)を使用すると、ドキュメントのライフサイクルの特定の時点でロジックを実行できます。フックに焦点を当て、不必要に操作をブロックすることを避けてください。
  5. データベースに依存しない -- Payload はデータベースアダプター(Postgres または MongoDB)を使用します。コレクションとフィールドは一度定義され、サポートされているすべてのデータベースで動作します。
  6. 型生成 -- payload generate:types を実行して、設定から TypeScript インターフェースを生成します。これにより、設定から API レスポンスまで、エンドツーエンドの型安全性が得られます。

Payload を使用する場面:

  • コンテンツ管理アプリケーション (ブログ、e コマース、マーケティング

(原文がここで切り詰められています)

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Payload CMS Patterns

Quick Guide: Use Payload for code-first content management with TypeScript. Define collections and globals as config objects with typed fields, hooks, and access control functions. Prefer the Local API (payload.find, payload.create) for server-side operations. Always generate TypeScript types from your config. Use database adapters (Postgres or MongoDB) and never hardcode credentials. Access control functions receive { req } with the authenticated user. Hooks run at the document lifecycle level (beforeChange, afterChange, etc.) and must not have side effects that block the request unless intentional.


<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST define access control on every collection — open collections are a security risk)

(You MUST use the Local API (payload.find, payload.create) for server-side data operations — it is zero-latency and fully typed)

(You MUST generate TypeScript types with payload generate:types after every schema change)

(You MUST keep JSX/React component imports OUT of the Payload config file — separate config and UI concerns)

(You MUST use overrideAccess: false when calling the Local API on behalf of a user — the default is true which bypasses all access control)

</critical_requirements>


Auto-detection: Payload, payload, payloadcms, @payloadcms, buildConfig, CollectionConfig, GlobalConfig, payload.config.ts, payload.find, payload.create, payload.update, payload.delete, payload.findByID, lexicalEditor, richText, beforeChange, afterChange, afterRead, beforeValidate, access control payload, upload collection, imageSizes, versions drafts

When to use:

  • Configuring payload.config.ts with database adapter, collections, and globals
  • Defining collection schemas with typed fields (text, richText, relationship, blocks, array, group, upload, select)
  • Implementing access control functions (role-based, ownership-based, field-level)
  • Writing collection hooks (beforeChange, afterChange, beforeRead, afterRead, beforeValidate, beforeDelete, afterDelete)
  • Querying data via Local API, REST API, or GraphQL
  • Setting up authentication collections with login, roles, and JWT
  • Configuring uploads/media with image sizes and mime type restrictions
  • Enabling versions and drafts on collections or globals
  • Customizing the admin panel (groups, hidden collections, custom components)

Key patterns covered:

  • payload.config.ts setup with buildConfig, database adapters, editor config
  • Collection config: slug, fields, hooks, access, auth, upload, versions, admin
  • Field types: text, richText, relationship, upload, blocks, array, group, select, tabs, checkbox, date, number, email, code, json, point, radio, textarea, row, collapsible
  • Access control: collection-level and field-level, returning boolean or Where query
  • Hooks: beforeChange, afterChange, beforeRead, afterRead, beforeValidate, beforeDelete, afterDelete, beforeOperation, afterOperation
  • Local API: payload.find, payload.findByID, payload.create, payload.update, payload.delete, payload.count
  • REST API: auto-generated endpoints at /api/{collection-slug}
  • Globals: singleton documents for site settings, navigation, footer
  • Auth collections: auth: true, roles, login strategies
  • Uploads: imageSizes, mimeTypes, media collections
  • Versions and drafts: versions: { drafts: true }
  • TypeScript type generation

When NOT to use:

  • Simple key-value storage (use a database directly)
  • Static site generation without content editing needs
  • Applications that only need a REST API without an admin panel (use a plain API framework)
  • Client-side data fetching patterns (Payload's Local API is server-only)

Detailed Resources:

  • For decision frameworks and anti-patterns, see reference.md

Core Setup & Collections:

  • examples/core.md — Config setup, collection definitions, field types, access control, hooks

Advanced Patterns:

  • examples/advanced.md — Globals, versions/drafts, uploads/media, auth collections, Local API, REST API

<philosophy>

Philosophy

Payload is a TypeScript-native headless CMS that treats your schema as code. Instead of clicking through a GUI to build content models, you define collections and globals as TypeScript config objects. Payload auto-generates an admin panel, REST API, GraphQL API, and a fully typed Local API from your config.

Core principles:

  1. Config-as-code -- Collections, globals, fields, hooks, and access control are all defined in TypeScript. Your schema is version-controlled, reviewable, and deployable like any other code.
  2. Three APIs from one config -- Every collection automatically gets a Local API (server-only, zero-latency), REST API (/api/{slug}), and GraphQL API. The Local API is the primary interface for server-side operations.
  3. Access control is mandatory -- Every collection should have explicit access functions. By default, Payload denies access to unauthenticated users, but you must define who can do what. Access functions can return a boolean or a Where query to scope results.
  4. Hooks for side effects -- Lifecycle hooks (beforeChange, afterChange, etc.) let you run logic at specific points in the document lifecycle. Keep hooks focused and avoid blocking operations unnecessarily.
  5. Database-agnostic -- Payload uses database adapters (Postgres or MongoDB). Your collections and fields are defined once and work with any supported database.
  6. Type generation -- Run payload generate:types to produce TypeScript interfaces from your config. This gives you end-to-end type safety from config to API responses.

When to use Payload:

  • Content-managed applications (blogs, e-commerce, marketing sites)
  • Applications needing an admin panel with role-based access
  • Projects requiring a typed CMS with version control over the schema
  • Multi-tenant applications using access control to scope data per tenant
  • Headless CMS backing a frontend framework

</philosophy>


<patterns>

Core Patterns

Pattern 1: payload.config.ts Setup

The config is the entry point. It defines the database adapter, collections, globals, editor, and admin settings. Always use env vars for credentials.

const config = buildConfig({
  db: postgresAdapter({ pool: { connectionString: process.env.DATABASE_URL } }),
  editor: lexicalEditor(),
  collections: [Posts, Users, Media],
  globals: [SiteSettings],
  admin: { user: Users.slug },
  typescript: { outputFile: "./src/payload-types.ts" },
  secret: process.env.PAYLOAD_SECRET!,
});

Never hardcode database URLs or secrets. Import collections from separate files. See examples/core.md for full Postgres and MongoDB adapter configs.


Pattern 2: Collection Config

Collections are the primary data model. Each generates a database table, admin UI, and API endpoints. Define access control per operation, use useAsTitle for admin display, and keep each collection in its own file.

const Posts: CollectionConfig = {
  slug: "posts",
  admin: { useAsTitle: "title" },
  access: {
    read: () => true,
    create: ({ req: { user } }) => Boolean(user),
    update: isAdminOrAuthor,
    delete: isAdmin,
  },
  hooks: {
    beforeChange: [setAuthorOnCreate],
    afterChange: [revalidatePostCache],
  },
  versions: { drafts: true },
  fields: [
    { name: "title", type: "text", required: true },
    { name: "content", type: "richText" },
    {
      name: "author",
      type: "relationship",
      relationTo: "users",
      required: true,
    },
  ],
};

See examples/core.md for full collection config with all field types, sidebar positioning, and SEO tabs.


Pattern 3: Access Control

Access functions receive { req } with the authenticated user. They return true/false or a Where query to scope results. Define reusable functions in a shared access/ directory.

// Return boolean for simple checks
const isAdmin: Access = ({ req: { user } }) => user?.role === "admin";

// Return Where query for scoped access — users see only their own documents
const isAdminOrSelf: Access = ({ req: { user } }) => {
  if (!user) return false;
  if (user.role === "admin") return true;
  return { author: { equals: user.id } };
};

Field-level access uses the same pattern on individual fields. See examples/core.md for reusable access functions and field-level access examples.


Pattern 4: Collection Hooks

Hooks run at specific points in the document lifecycle. beforeChange returns modified data, afterChange is for non-blocking side effects. Use req.payload to access the Local API within hooks. Hooks receive a context object to prevent infinite loops when hooks trigger other operations.

beforeChange: [
  ({ data, operation, req }) => {
    if (operation === "create" && req.user) data.author = req.user.id;
    return data;
  },
],
afterChange: [
  ({ doc, operation, req, context }) => {
    if (context.skipRevalidation) return;
    if (operation === "create") req.payload.logger.info(`Post created: ${doc.title}`);
  },
],

Never put blocking external API calls in beforeChange -- use afterChange for non-critical side effects. See examples/core.md for hook patterns and examples/advanced.md for cross-collection hooks.


Pattern 5: Field Types

Payload provides typed fields: text, richText, number, select, checkbox, date, email, textarea, relationship, upload, json, code, point, radio. Structural fields compose to model any content shape:

  • group -- nested object with sub-fields
  • array -- repeatable rows of same-shape fields
  • blocks -- flexible content with multiple block types (use interfaceName for custom TypeScript interface names)
  • tabs, row, collapsible -- admin-only layout helpers that do not affect data shape

Use blocks when editors choose from multiple block types for flexible page layouts. Use array when every row has the same fields. See examples/core.md for block definitions and reference.md for the complete field type table.


Pattern 6: Local API

The Local API is the primary server-side interface -- zero-latency, fully typed, and executes hooks and access control. Always pass overrideAccess: false when operating on behalf of a user.

const payload = await getPayload({ config });
const result = await payload.find({
  collection: "posts",
  where: { status: { equals: "published" } },
  sort: "-createdAt",
  limit: 20,
  depth: 1,
  overrideAccess: false,
});

Without overrideAccess: false, access control is completely bypassed (the default is true). See examples/advanced.md for full CRUD operations, bulk updates, and globals API.

</patterns>


<decision_framework>

Decision Framework

Which API to Use

Where is the code running?
+-- Server-side (API route, server component, script)
|   +-- Local API (zero-latency, fully typed, preferred)
+-- External client (browser, mobile app, third-party)
|   +-- REST API (/api/{collection-slug})
+-- GraphQL client
    +-- GraphQL API (/api/graphql)

Field Type Selection

What kind of data?
+-- Single value
|   +-- Short text --> text
|   +-- Long text --> textarea
|   +-- Rich content --> richText
|   +-- Number --> number
|   +-- Boolean --> checkbox
|   +-- Date/time --> date
|   +-- Email --> email
|   +-- Coordinates --> point
|   +-- Code snippet --> code
|   +-- Arbitrary JSON --> json
+-- Choice from options
|   +-- Single choice (dropdown) --> select
|   +-- Single choice (visible) --> radio
|   +-- Linked document --> relationship
|   +-- File/image --> upload
+-- Nested structure
|   +-- Fixed group of fields --> group
|   +-- Repeatable rows (same shape) --> array
|   +-- Flexible content (multiple block types) --> blocks
+-- Admin layout only (no data effect)
    +-- Tabbed sections --> tabs
    +-- Side-by-side fields --> row
    +-- Collapsible section --> collapsible

Access Control Strategy

Who should access this data?
+-- Public (anyone) --> read: () => true
+-- Authenticated users only --> read: ({ req: { user } }) => Boolean(user)
+-- Admin only --> read: ({ req: { user } }) => user?.role === 'admin'
+-- Owner only --> read: return Where query matching user.id
+-- Mixed (public read, auth write) --> Different function per operation
+-- Field-level restriction --> access on individual field config

Hooks vs Access Control

What do you need to do?
+-- Control WHO can do something --> Access control
+-- Control WHAT happens when they do it --> Hooks
+-- Validate data before saving --> beforeValidate hook or field validation
+-- Transform data before saving --> beforeChange hook
+-- Trigger side effects after saving --> afterChange hook
+-- Filter/transform output --> afterRead hook

</decision_framework>


<red_flags>

RED FLAGS

High Priority Issues:

  • Missing access control on collections -- Without explicit access functions, Payload denies all access to unauthenticated users but grants full access to any authenticated user. Always define explicit access rules.
  • overrideAccess default is true in Local API -- Every payload.find(), payload.create(), etc. call bypasses access control by default. Always pass overrideAccess: false when operating on behalf of a user.
  • Importing JSX/React components in payload.config.ts -- Payload config runs in a Node context. Importing React components (even transitively) causes bundling errors. Keep config and UI imports completely separate.
  • Hardcoded secret or database URL -- Use environment variables. The Payload secret is used to sign JWTs; hardcoding it is a security vulnerability.

Medium Priority Issues:

  • *Using `select("")equivalent** -- In the Local API, not specifyingselectreturns all fields. Use theselect` option to fetch only needed fields for performance.
  • Deep depth values -- Default depth is 2. High depth values cause cascading relationship queries. Set depth: 0 or depth: 1 unless you need deeply nested relationships.
  • Blocking hooks with external calls -- beforeChange and beforeValidate hooks block the save operation. Move non-critical external API calls to afterChange or use background processing.
  • Not running payload generate:types after schema changes -- Stale types lead to runtime errors that TypeScript should have caught at compile time.

Common Mistakes:

  • Deep-cloning collection configs -- JSON.parse(JSON.stringify(config)) strips hooks and access functions (they are functions, not serializable data). Use spread or Object.assign instead.
  • Forgetting .select() equivalent after create/update -- In the Local API, payload.create and payload.update return the full document by default. Use the select option if you need specific fields.
  • Using FOR ALL style access -- Define separate access functions for create, read, update, delete instead of a single function. Different operations have different security requirements.
  • Monorepo version mismatches -- All packages in a monorepo must use the same version of payload, @payloadcms/*, next, react, and react-dom. Mismatches cause subtle bundling errors.

Gotchas & Edge Cases:

  • beforeChange data is a partial on update -- On update operations, data contains only the changed fields, not the full document. Use originalDoc to access existing values.
  • beforeChange has no id on create -- The document ID is not available during beforeChange on create operations. If you need the ID, use afterChange.
  • overrideAccess defaults -- Local API defaults to true (bypass access control). REST and GraphQL always enforce access control. This asymmetry is intentional but catches people off guard.
  • Tabs, rows, and collapsibles do not affect data shape -- These are admin-only layout fields. A field inside a tab is stored at the top level of the document, not nested.
  • Relationship depth cascading -- Setting depth: 3 on a collection with circular relationships can cause exponential query growth. Keep depth as low as possible.
  • Auth collections auto-inject fields -- Collections with auth: true automatically get email, hash, salt, loginAttempts, and lockUntil fields. Do not redefine them.
  • Versions create a separate table -- Enabling versions: true creates a _posts_versions table (or equivalent). This can significantly increase storage for high-traffic collections.
  • Access control Where queries run as SQL -- When an access function returns a Where query instead of a boolean, it is appended to the database query. Complex Where queries can impact database performance.

</red_flags>


<critical_reminders>

CRITICAL REMINDERS

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST define access control on every collection — open collections are a security risk)

(You MUST use the Local API (payload.find, payload.create) for server-side data operations — it is zero-latency and fully typed)

(You MUST generate TypeScript types with payload generate:types after every schema change)

(You MUST keep JSX/React component imports OUT of the Payload config file — separate config and UI concerns)

(You MUST use overrideAccess: false when calling the Local API on behalf of a user — the default is true which bypasses all access control)

Failure to follow these rules will create security vulnerabilities, type-unsafe operations, and bundling errors.

</critical_reminders>