Custom Fields
Rather than repeating field definitions across every collection, the boilerplate centralises common patterns in src/fields/. You spread or call them wherever needed. Change the definition in one place and everything stays in sync.
Slug Field
Section titled “Slug Field”import { slugField } from '@/fields/slug';
export const pages: CollectionConfig = { fields: [ { name: 'title', type: 'text', required: true }, ...slugField('title'), ],};slugField spreads two fields into your collection: a read-only slug input and a hidden sync button. It watches the source field ('title' here) and auto-populates the slug as the editor types. The editor can also override it manually.
Options:
...slugField('title', { slug: { admin: { placeholder: 'custom-placeholder' }, },})Link Field
Section titled “Link Field”import { linkField } from '@/fields/link';
export const pages: CollectionConfig = { fields: [ { name: 'cta', type: 'group', ...linkField(), }, ],};linkField adds a complete link group — type selector, reference picker, URL input, link text, style, and new-tab toggle — in a single spread. It handles the internal/external distinction so you do not have to build that logic per collection.
Link structure:
| Field | Type | Description |
|---|---|---|
type | select | internal_link or custom_url |
reference | relationship | Internal page/post link |
url | text | External URL (validated) |
text | text | Link text |
style | select | Link style variant |
newTab | checkbox | Open in new tab |
Render it in the frontend with CMSLink, which resolves internal references to their correct path automatically:
import CMSLink from '@/components/cms-link/cms-link';
<CMSLink link={doc.cta} />;Upload Fields
Section titled “Upload Fields”import { imageUpload } from '@/fields/upload/image';
export const image: Block = { slug: 'image', fields: [ imageUpload({ name: 'image', relationTo: 'media', }), ],};imageUpload and videoUpload are pre-configured upload fields that include focal point support and the correct relation to the media collection. Use them instead of raw upload fields so focal point handling stays consistent.
Adding a Custom Field
Section titled “Adding a Custom Field”-
Create the field config in
src/fields/src/fields/my-field/my-field.ts import type { Field } from 'payload';export const myField = (name: string, options?: Partial<Field>): Field => ({name,type: 'text',required: true,...options,});The function accepts a name and an optional overrides object. Spreading
optionslast means callers can override any default —required,adminsettings, validation hooks — without touching the definition itself. -
Export from the fields index
src/fields/index.ts export { slugField } from './slug/slug';export { linkField } from './link/link';export { imageUpload, videoUpload } from './upload';export { myField } from './my-field/my-field';All fields are exported from a single index so imports stay clean across collections:
import { myField } from '@/fields'. -
Use in collections
src/collections/events.ts import { myField } from '@/fields';fields: [myField('title')];