payload
Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validati…
它会碰到什么
逐条看命中(5 条严重或高危)
- 高
SKILL.md:132identity-config-writehooks: { - 高
SKILL.md:269identity-config-writehooks: { - 高
SKILL.md:282identity-config-writehooks: { - 高
SKILL.md:303identity-config-writehooks: { - 高
SKILL.md:317identity-config-writehooks: {
这一栏是扫描器报的事实,不是结论。命中多不等于有毒(安全工具、规则库、示例脚本本来就会包含危险写法),命中少也不等于干净。它和你手上的凭据、文件、网络有什么关系,需要你自己看。
技能内容
Payload CMS Application Development
Payload is a Next.js native CMS with TypeScript-first architecture, providing admin panel, database management, REST/GraphQL APIs, authentication, and file storage.
Quick Reference
| Task | Solution | Details |
| ------------------------ | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Auto-generate slugs | slugField() | [FIELDS.md#slug-field-helper](reference/FIELDS.md#slug-field-helper) |
| Restrict content by user | Access control with query | [ACCESS-CONTROL.md#row-level-security-with-complex-queries](reference/ACCESS-CONTROL.md#row-level-security-with-complex-queries) |
| Local API user ops | user + overrideAccess: false | [QUERIES.md#access-control-in-local-api](reference/QUERIES.md#access-control-in-local-api) |
| Draft/publish workflow | versions: { drafts: true } | [COLLECTIONS.md#versioning--drafts](reference/COLLECTIONS.md#versioning--drafts) |
| Computed fields | virtual: true with afterRead | [FIELDS.md#virtual-fields](reference/FIELDS.md#virtual-fields) |
| Conditional fields | admin.condition | [FIELDS.md#conditional-fields](reference/FIELDS.md#conditional-fields) |
| Custom field validation | validate function | [FIELDS.md#validation](reference/FIELDS.md#validation) |
| Filter relationship list | filterOptions on field | [FIELDS.md#relationship](reference/FIELDS.md#relationship) |
| Select specific fields | select parameter | [QUERIES.md#field-selection](reference/QUERIES.md#field-selection) |
| Auto-set author/dates | beforeChange hook | [HOOKS.md#collection-hooks](reference/HOOKS.md#collection-hooks) |
| Prevent hook loops | req.context check | [HOOKS.md#context](reference/HOOKS.md#context) |
| Cascading deletes | beforeDelete hook | [HOOKS.md#collection-hooks](reference/HOOKS.md#collection-hooks) |
| Geospatial queries | point field with near/within | [FIELDS.md#point-geolocation](reference/FIELDS.md#point-geolocation) |
| Reverse relationships | join field type | [FIELDS.md#join-fields](reference/FIELDS.md#join-fields) |
| Next.js revalidation | Context control in afterChange | [HOOKS.md#nextjs-revalidation-with-context-control](reference/HOOKS.md#nextjs-revalidation-with-context-control) |
| Query by relationship | Nested property syntax | [QUERIES.md#nested-properties](reference/QUERIES.md#nested-properties) |
| Complex queries | AND/OR logic | [QUERIES.md#andor-logic](reference/QUERIES.md#andor-logic) |
| Transactions | Pass req to operations | [ADAPTERS.md#threading-req-through-operations](reference/ADAPTERS.md#threading-req-through-operations) |
| Background jobs | Jobs queue with tasks | [ADVANCED.md#jobs-queue](reference/ADVANCED.md#jobs-queue) |
| Custom API routes | Collection custom endpoints | [ADVANCED.md#custom-endpoints](reference/ADVANCED.md#custom-endpoints) |
| Cloud storage | Storage adapter plugins | [ADAPTERS.md#storage-adapters](reference/ADAPTERS.md#storage-adapters) |
| Multi-language | localization config + localized: true | [ADVANCED.md#localization](reference/ADVANCED.md#localization) |
| Create plugin | (options) => (config) => Config | [PLUGIN-DEVELOPMENT.md#plugin-architecture](reference/PLUGIN-DEVELOPMENT.md#plugin-architecture) |
| Plugin package setup | Package structure with SWC | [PLUGIN-DEVELOPMENT.md#plugin-package-structure](reference/PLUGIN-DEVELOPMENT.md#plugin-package-structure) |
| Add fields to collection | Map collections, spread fields | [PLUGIN-DEVELOPMENT.md#adding-fields-to-collections](reference/PLUGIN-DEVELOPMENT.md#adding-fields-to-collections) |
| Plugin hooks | Preserve existing hooks in array | [PLUGIN-DEVELOPMENT.md#adding-hooks](reference/PLUGIN-DEVELOPMENT.md#adding-hooks) |
| Check field type | Type guard functions | [FIELD-TYPE-GUARDS.md](reference/FIELD-TYPE-GUARDS.md) |
Quick Start
npx create-payload-app@latest my-app
cd my-app
pnpm dev
Minimal Config
import { buildConfig } from 'payload'
import { mongooseAdapter } from '@payloadcms/db-mongodb'
import { lexicalEditor } from '@payloadcms/richtext-lexical'
import path from 'path'
import { fileURLToPath } from 'url'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
export default buildConfig({
admin: {
user: 'users',
importMap: {
baseDir: path.resolve(dirname),
},
},
collections: [Users, Media],
editor: lexicalEditor(),
secret: process.env.PAYLOAD_SECRET,
typescript: {
outputFile: path.resolve(dirname, 'payload-types.ts'),
},
db: mongooseAdapter({
url: process.env.DATABASE_URI,
}),
})
Essential Patterns
Basic Collection
import type { CollectionConfig } from 'payload'
export const Posts: CollectionConfig = {
slug: 'posts',
admin: {
useAsTitle: 'title',
defaultColumns: ['title', 'author', 'status', 'createdAt'],
},
fields: [
{ name: 'title', type: 'text', required: true },
{ name: 'slug', type: 'text', unique: true, index: true },
{ name: 'content', type: 'richText' },
{ name: 'author', type: 'relationship', relationTo: 'users' },
],
timestamps: true,
}
For more collection patterns (auth, upload, drafts, live preview), see [COLLECTIONS.md](reference/COLLECTIONS.md).
Common Fields
// Text field
{ name: 'title', type: 'text', required: true }
// Relationship
{ name: 'author', type: 'relationship', relationTo: 'users', required: true }
// Rich text
{ name: 'content', type: 'richText', required: true }
// Select
{ name: 'status', type: 'select', options: ['draft', 'published'], defaultValue: 'draft' }
// Upload
{ name: 'image', type: 'upload', relationTo: 'media' }
For all field types (array, blocks, point, join, virtual, conditional, etc.), see [FIELDS.md](reference/FIELDS.md).
Hook Example
export const Posts: CollectionConfig = {
slug: 'posts',
hooks: {
beforeChange: [
async ({ data, operation }) => {
if (operation === 'create') {
data.slug = slugify(data.title)
}
return data
},
],
},
fields: [{ name: 'title', type: 'text' }],
}
For all hook patterns, see [HOOKS.md](reference/HOOKS.md). For access control, see [ACCESS-CONTROL.md](reference/ACCESS-CONTROL.md).
Access Control with Type Safety
import type { Access } from 'payload'
import type { User } from '@/payload-types'
// Type-safe access control
export const adminOnly: Access = ({ req }) => {
const user = req.user as User
return user?.roles?.includes('admin') || false
}
// Row-level access control
export const ownPostsOnly: Access = ({ req }) => {
const user = req.user as User
if (!user) return false
if (user.roles?.includes('admin')) return true
return {
author: { equals: user.id },
}
}
Query Example
// Local API
const posts = await payload.find({
collection: 'posts',
where: {
status: { equals: 'published' },
'author.name': { contains: 'john' },
},
depth: 2,
limit: 10,
sort: '-createdAt',
})
// Query with populated relationships
const post = await payload.findByID({
collection: 'posts',
id: '123',
depth: 2, // Populates relationships (default is 2)
})
// Returns: { author: { id: "user123", name: "John" } }
// Without depth, relationships return IDs only
const post = await payload.findByID({
collection: 'posts',
id: '123',
depth: 0,
})
// Returns: { author: "user123" }
For all query operators and REST/GraphQL examples, see [QUERIES.md](reference/QUERIES.md).
Getting Payload Instance
// In API routes (Next.js)
import { getPayload } from 'payload'
import config from '@payload-config'
export async function GET() {
const payload = await getPayload({ config })
const posts = await payload.find({
collection: 'posts',
})
return Response.json(posts)
}
// In Server Components
import { getPayload } from 'payload'
import config from '@payload-config'
export default async function Page() {
const payload = await getPayload({ config })
const { docs } = await payload.find({ collection: 'posts' })
return <div>{docs.map(post => <h1 key={post.id}>{post.title}</h1>)}</div>
}
Security Pitfalls
1. Local API Access Control (CRITICAL)
By default, Local API operations bypass ALL access control, even when passing a user.
// ❌ SECURITY BUG: Passes user but ignores their permissions
await payload.find({
collection: 'posts',
user: someUser, // Access control is BYPASSED!
})
// ✅ SECURE: Actually enforces the user's permissions
await payload.find({
collection: 'posts',
user: someUser,
overrideAccess: false, // REQUIRED for access control
})
When to use each:
overrideAccess: true(default) - Server-side operations you trust (cron jobs, system tasks)overrideAccess: false- When operating on behalf of a user (API routes, webhooks)
See [QUERIES.md#access-control-in-local-api](reference/QUERIES.md#access-control-in-local-api).
2. Transaction Failures in Hooks
Nested operations in hooks without req break transaction atomicity.
// ❌ DATA CORRUPTION RISK: Separate transaction
hooks: {
afterChange: [
async ({ doc, req }) => {
await req.payload.create({
collection: 'audit-log',
data: { docId: doc.id },
// Missing req - runs in separate transaction!
})
},
]
}
// ✅ ATOMIC: Same transaction
hooks: {
afterChange: [
async ({ doc, req }) => {
await req.payload.create({
collection: 'audit-log',
data: { docId: doc.id },
req, // Maintains atomicity
})
},
]
}
See [ADAPTERS.md#threading-req-through-operations](reference/ADAPTERS.md#threading-req-through-operations).
3. Infinite Hook Loops
Hooks triggering operations that trigger the same hooks create infinite loops.
// ❌ INFINITE LOOP
hooks: {
afterChange: [
async ({ doc, req }) => {
await req.payload.update({
collection: 'posts',
id: doc.id,
data: { views: doc.views + 1 },
req,
}) // Triggers afterChange again!
},
]
}
// ✅ SAFE: Use context flag
hooks: {
afterChange: [
async ({ doc, req, context }) => {
if (context.skipHooks) return
await req.payload.update({
collection: 'posts',
id: doc.id,
data: { views: doc.views + 1 },
context: { skipHooks: true },
req,
})
},
]
}
See [HOOKS.md#context](reference/HOOKS.md#context).
Project Structure
src/
├── app/
│ ├── (frontend)/
│ │ └── page.tsx
│ └── (payload)/
│ └── admin/[[...segments]]/page.tsx
├── collections/
│ ├── Posts.ts
│ ├── Media.ts
│ └── Users.ts
├── globals/
│ └── Header.ts
├── components/
│ └── CustomField.tsx
├── hooks/
│ └── slugify.ts
└── payload.config.ts
Type Generation
// payload.config.ts
export default buildConfig({
typescript: {
outputFile: path.resolve(dirname, 'payload-types.ts'),
},
// ...
})
// Usage
import type { Post, User } from '@/payload-types'
Reference Documentation
- [FIELDS.md](reference/FIELDS.md) - All field types, validation, admin options
- [FIELD-TYPE-GUARDS.md](reference/FIELD-TYPE-GUARDS.md) - Type guards for runtime field type checking and narrowing
- [COLLECTIONS.md](reference/COLLECTIONS.md) - Collection configs, auth, upload, drafts, live preview
- [HOOKS.md](reference/HOOKS.md) - Collection hooks, field hooks, context patterns
- [ACCESS-CONTROL.md](reference/ACCESS-CONTROL.md) - Collection, field, global access control, RBAC, multi-tenant
- [ACCESS-CONTROL-ADVANCED.md](reference/ACCESS-CONTROL-ADVANCED.md) - Context-aware, time-based, subscription-based access, factory functions, templates
- [QUERIES.md](reference/QUERIES.md) - Query operators, Local/REST/GraphQL APIs
- [ENDPOINTS.md](reference/ENDPOINTS.md) - Custom API endpoints: authentication, helpers, request/response patterns
- [ADAPTERS.md](reference/ADAPTERS.md) - Database, storage, email adapters, transactions
- [ADVANCED.md](reference/ADVANCED.md) - Authentication, jobs, endpoints, components, plugins, localization
- [PLUGIN-DEVELOPMENT.md](reference/PLUGIN-DEVELOPMENT.md) - Plugin architecture, monorepo structure, patterns, best practices
Resources
- llms-full.txt: <https://payloadcms.com/llms-full.txt>
- Docs: <https://payloadcms.com/docs>
- GitHub: <https://github.com/payloadcms/payload>
- Examples: <https://github.com/payloadcms/payload/tree/main/examples>
- Templates: <https://github.com/payloadcms/payload/tree/main/templates>
想直接用这个技能?
本站把开放许可(MIT / Apache 等)的技能按仓库打包整理到网盘,点一下转存到你自己的网盘,不用一个个从 GitHub 拉。许可未声明的技能只给原始仓库链接,不打包。
它属于哪个仓库
skills_categorized/backend/payload/SKILL.md同一个仓库里的其他技能
同名技能的其他版本
有 16 个不同仓库或目录里都有叫 payload 的技能。它们内容并不相同,别混用:
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,
- Microck/ordinary-claude-skills — Use when working with Payload CMS projects (payload.config.ts, collections, fields, hooks,