8.8 KiB
8.8 KiB
Payload CMS Advanced Features
Complete reference for authentication, jobs, custom endpoints, components, plugins, and localization.
Authentication
Login
// REST API
const response = await fetch('/api/users/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email: 'user@example.com',
password: 'password',
}),
})
// Local API
const result = await payload.login({
collection: 'users',
data: {
email: 'user@example.com',
password: 'password',
},
})
Forgot Password
await payload.forgotPassword({
collection: 'users',
data: {
email: 'user@example.com',
},
})
Custom Strategy
import type { CollectionConfig, Strategy } from 'payload'
const customStrategy: Strategy = {
name: 'custom',
authenticate: async ({ payload, headers }) => {
const token = headers.get('authorization')?.split(' ')[1]
if (!token) return { user: null }
const user = await verifyToken(token)
return { user }
},
}
export const Users: CollectionConfig = {
slug: 'users',
auth: {
strategies: [customStrategy],
},
fields: [],
}
API Keys
import type { CollectionConfig } from 'payload'
export const APIKeys: CollectionConfig = {
slug: 'api-keys',
auth: {
disableLocalStrategy: true,
useAPIKey: true,
},
fields: [],
}
Jobs Queue
Offload long-running or scheduled tasks to background workers.
Tasks
import { buildConfig } from 'payload'
import type { TaskConfig } from 'payload'
export default buildConfig({
jobs: {
tasks: [
{
slug: 'sendWelcomeEmail',
inputSchema: [
{ name: 'userEmail', type: 'text', required: true },
{ name: 'userName', type: 'text', required: true },
],
outputSchema: [{ name: 'emailSent', type: 'checkbox', required: true }],
retries: 2, // Retry up to 2 times on failure
handler: async ({ input, req }) => {
await sendEmail({
to: input.userEmail,
subject: `Welcome ${input.userName}`,
})
return { output: { emailSent: true } }
},
} as TaskConfig<'sendWelcomeEmail'>,
],
},
})
Queueing Jobs
// In a hook or endpoint
await req.payload.jobs.queue({
task: 'sendWelcomeEmail',
input: {
userEmail: 'user@example.com',
userName: 'John',
},
waitUntil: new Date('2024-12-31'), // Optional: schedule for future
})
Workflows
Multi-step jobs that run in sequence:
{
slug: 'onboardUser',
inputSchema: [{ name: 'userId', type: 'text' }],
handler: async ({ job, req }) => {
const results = await job.runInlineTask({
task: async ({ input }) => {
// Step 1: Send welcome email
await sendEmail(input.userId)
return { output: { emailSent: true } }
},
})
await job.runInlineTask({
task: async () => {
// Step 2: Create onboarding tasks
await createTasks()
return { output: { tasksCreated: true } }
},
})
},
}
Custom Endpoints
Add custom REST API routes to collections, globals, or root config. See ENDPOINTS.md for detailed patterns, authentication, helpers, and real-world examples.
Root Endpoints
import { buildConfig } from 'payload'
import type { Endpoint } from 'payload'
const helloEndpoint: Endpoint = {
path: '/hello',
method: 'get',
handler: () => {
return Response.json({ message: 'Hello!' })
},
}
const greetEndpoint: Endpoint = {
path: '/greet/:name',
method: 'get',
handler: (req) => {
return Response.json({
message: `Hello ${req.routeParams.name}!`,
})
},
}
export default buildConfig({
endpoints: [helloEndpoint, greetEndpoint],
collections: [],
secret: process.env.PAYLOAD_SECRET || '',
})
Collection Endpoints
import type { CollectionConfig, Endpoint } from 'payload'
const featuredEndpoint: Endpoint = {
path: '/featured',
method: 'get',
handler: async (req) => {
const posts = await req.payload.find({
collection: 'posts',
where: { featured: { equals: true } },
})
return Response.json(posts)
},
}
export const Posts: CollectionConfig = {
slug: 'posts',
endpoints: [featuredEndpoint],
fields: [
{ name: 'title', type: 'text' },
{ name: 'featured', type: 'checkbox' },
],
}
Custom Components
Field Component (Client)
'use client'
import { useField } from '@payloadcms/ui'
import type { TextFieldClientComponent } from 'payload'
export const CustomField: TextFieldClientComponent = () => {
const { value, setValue } = useField()
return <input value={value || ''} onChange={(e) => setValue(e.target.value)} />
}
Custom View
'use client'
import { DefaultTemplate } from '@payloadcms/next/templates'
export const CustomView = () => {
return (
<DefaultTemplate>
<h1>Custom Dashboard</h1>
{/* Your content */}
</DefaultTemplate>
)
}
Admin Config
import { buildConfig } from 'payload'
export default buildConfig({
admin: {
components: {
beforeDashboard: ['/components/BeforeDashboard'],
beforeLogin: ['/components/BeforeLogin'],
views: {
custom: {
Component: '/views/Custom',
path: '/custom',
},
},
},
},
collections: [],
secret: process.env.PAYLOAD_SECRET || '',
})
Plugins
Available Plugins
- @payloadcms/plugin-seo - SEO fields with meta title/description, Open Graph, preview generation
- @payloadcms/plugin-redirects - Manage URL redirects (301/302) for Next.js apps
- @payloadcms/plugin-nested-docs - Hierarchical document structures with breadcrumbs
- @payloadcms/plugin-form-builder - Dynamic form builder with submissions and validation
- @payloadcms/plugin-search - Full-text search integration (Algolia support)
- @payloadcms/plugin-stripe - Stripe payments, subscriptions, webhooks
- @payloadcms/plugin-ecommerce - Complete ecommerce solution (products, variants, carts, orders)
- @payloadcms/plugin-import-export - Import/export data via CSV
- @payloadcms/plugin-multi-tenant - Multi-tenancy with tenant isolation
- @payloadcms/plugin-sentry - Sentry error tracking integration
- @payloadcms/plugin-mcp - Model Context Protocol for AI integrations
Using Plugins
import { buildConfig } from 'payload'
import { seoPlugin } from '@payloadcms/plugin-seo'
import { redirectsPlugin } from '@payloadcms/plugin-redirects'
export default buildConfig({
plugins: [
seoPlugin({
collections: ['posts', 'pages'],
}),
redirectsPlugin({
collections: ['pages'],
}),
],
collections: [],
secret: process.env.PAYLOAD_SECRET || '',
})
Creating Plugins
import type { Config } from 'payload'
interface PluginOptions {
enabled?: boolean
}
export const myPlugin =
(options: PluginOptions) =>
(config: Config): Config => ({
...config,
collections: [
...(config.collections || []),
{
slug: 'plugin-collection',
fields: [{ name: 'title', type: 'text' }],
},
],
onInit: async (payload) => {
if (config.onInit) await config.onInit(payload)
// Plugin initialization
},
})
Localization
import { buildConfig } from 'payload'
import type { Field, Payload } from 'payload'
export default buildConfig({
localization: {
locales: ['en', 'es', 'de'],
defaultLocale: 'en',
fallback: true,
},
collections: [],
secret: process.env.PAYLOAD_SECRET || '',
})
// Localized field
const localizedField: TextField = {
name: 'title',
type: 'text',
localized: true,
}
// Query with locale
const posts = await payload.find({
collection: 'posts',
locale: 'es',
})
TypeScript Type References
For complete TypeScript type definitions and signatures, reference these files from the Payload source:
Core Configuration Types
- All Commonly-Used Types - Check here first for commonly used types and interfaces. All core types are exported from this file.
Database & Adapters
- Database Adapter Types - Base adapter interface
- MongoDB Adapter - MongoDB-specific options
- Postgres Adapter - Postgres-specific options
Rich Text & Plugins
- Lexical Types - Lexical editor configuration
When users need detailed type information, fetch these URLs to provide complete signatures and optional parameters.