Choose the content model
Use page blocks first, then add collections and editor fields only where the content requires them.
On this page
GoalLink to this section
Give the client enough structure to edit safely without making each section a fixed form. Northline's service descriptions and team introduction can remain page blocks.
1. Start with native compositionLink to this section
Use the default page template for Services, About and Contact. Compose sections, columns, cards, quotes and forms in the root content editor.
Use a custom template when the page requires a different shell or fixed data. Use a custom collection when the same records are read from several places. A four-card services row alone does not require a Services collection.
| Need | Choose |
|---|---|
| Reorder text, media and sections | Native page blocks |
| Reuse an editorial composition | Components collection |
| Change a page shell | Custom page template |
| Render data shared across pages | Custom collection |
| Render a layout no native block supports | Custom block |
2. Choose the smallest editor tierLink to this section
| Builder | Field role |
|---|---|
rootLexicalEditor | Page body with section-level composition |
regionLexicalEditor | Content inside a section, feature or column region |
fragmentLexicalEditor | Content inside a card or accordion |
slotLexicalEditor | Short captions and labels |
import type { Block } from 'payload'
import { regionLexicalEditor } from '@systhemaui/payload/lexical/editors'
export const CompanyNoteSchema: Block = {
slug: 'companyNote',
interfaceName: 'CompanyNoteBlock',
fields: [
{ name: 'heading', type: 'text', required: true },
{ name: 'content', type: 'richText', editor: regionLexicalEditor() },
],
}This schema is completed and registered in Custom block. The region editor belongs inside the section this block renders.
See Lexical editors for the full matrix.
3. Add shared records only when requiredLink to this section
If the client later needs office details reused on several pages, define an Offices collection with explicit access rules:
import type { CollectionConfig } from 'payload'
import { requireCapability } from '@systhemaui/payload'
export const Offices: CollectionConfig = {
slug: 'offices',
access: {
read: () => true,
create: requireCapability('offices.create'),
update: requireCapability('offices.update'),
delete: requireCapability('offices.delete'),
},
fields: [
{ name: 'name', type: 'text', required: true },
{ name: 'address', type: 'textarea', required: true },
],
}Register it through customCollections: [Offices] in the existing plugin options. The offices.* strings are project-defined capabilities. Register them with roles.customCapabilities and grant them through roles.customRoles or roles.overrideRoles; custom collections are not automatically granted to the built-in admin role. See Access control.
Do not add this collection to the tutorial unless you need the shared records.
4. Regenerate the schema outputsLink to this section
pnpm sync
pnpm exec tsc --noEmitSchema changes can require database migrations before deployment. Follow the site's database lane in Upgrading a client site.
Check your workLink to this section
- Editors can reorder the ordinary page content.
- Short fields do not expose page-level layout controls.
- Any custom collection has reviewed read and write access.
- Types and the Admin import map regenerate without errors.