Pages, Blocks & Posts
Content is managed in Payload via Pages, Posts, and Categories. Pages compose 15 blocks via the page builder; posts are a traditional title/slug/content blog model. Both are tenant-scoped — each site has its own pages, posts, and categories.
Pages
Pages are the primary way to build a tenant’s frontend. Each page has a slug, SEO metadata, and a layout field that holds an ordered list of blocks.
The block library (15 blocks)
All blocks live in src/domains/cms/payload/blocks/. Every block shares a Section tab (variant, padding, content header).
Layout
| Block | Slug | What it does |
|---|---|---|
| Hero Section | hero-section-block | Full-width hero with optional media |
| Logocloud Section | logocloud-section-block | Grid or row of logos |
| Feature Section | feature-section-block | 2- or 3-column feature grid (Lucide icons) |
| Feature Showcase | feature-showcase-section-block | Alternating media + text sections |
| Bento Section | bento-section-block | Fixed bento grid layout |
Content
| Block | Slug | What it does |
|---|---|---|
| Content Block | content-block | Lexical rich text |
| Content Section | content-section-block | Rich text body with sticky image |
| Media Block | media-block | Single image/video with optional caption |
Commerce — blocks with brains (Stripe-connected)
| Block | Slug | What it does |
|---|---|---|
| Pricing Section | pricing-section-block | Pulls live Stripe products, monthly/annual toggle, real checkout |
| Product Grid | product-grid-block | Live Stripe prices, checkout |
Browse — driven by the data layer
| Block | Slug | What it does |
|---|---|---|
| Explore Section | explore-section-block | Per-tenant Orama search over records. Variants: grid / table / feed / map / minimal. See Data → Search & Explore. |
Social proof
| Block | Slug | What it does |
|---|---|---|
| Testimonial Section | testimonial-section-block | Quote, author, role, avatar |
| Blog Section | blog-section-block | Live posts query, grid or list |
Engagement
| Block | Slug | What it does |
|---|---|---|
| FAQ Section | faq-section-block | Accordion |
| CTA Section | cta-section-block | Title + description + buttons |
| Newsletter Section | newsletter-section-block | Lead capture + UTM tracking + welcome email |
Shared section controls
Every section block has a Section tab:
- Full width — stretch to the viewport edges
- Variant —
background,muted,primary,secondary - Padding — top/bottom toggles
- Separators — top/bottom divider lines
- Content header — optional eyebrow, title, description, buttons above the block’s main content
Drafts and autosave
Pages have drafts with autosave and scheduled publishing. Up to 100 versions per page. Live preview is wired via @payloadcms/plugin-live-preview.
SEO
The SEO tab (via @payloadcms/plugin-seo) overrides meta title, description, and preview image. If empty, the tenant’s defaults are used. JSON-LD is auto-emitted on detail pages and per record (see Data → Search & Explore).
Composing pages
Two paths:
- Admin — drag blocks in the page builder UI.
- CLI / agent —
shipmore page block-schemadiscovers the shape,shipmore page buildcomposes the page from a JSON spec:
shipmore page block-schema --name explore-section-block
shipmore page build --tenant ramen.example.com --slug home --title "Browse Ramen Shops" \
--blocks '[{"type":"explore-section-block","content":{"title":"Browse","pageSize":20}}]'page build returns the correct tenant-scoped URL — use response.url verbatim, don’t reconstruct it.
ComposerService (templates)
The ComposerService (src/domains/cms/composer/) assembles blocks into pages and multi-page projects from a template or a structured brief. This enables agent prompts like “create a lander for doctors”.
- Templates live in code (
src/domains/cms/composer/templates.ts), not in the DB. - Projects are ephemeral:
ComposerService.createProject()callsPageService.createPage()N times and returns IDs. There is noprojectscollection.
Agent: "create a doctor landing page"
→ ComposerService.createProject({ template: 'service-lander', tenantId })
→ selects: hero + feature-showcase + testimonials + pricing + newsletter + cta
→ calls PageService.createPage() with those blocks
→ returns { pageId, slug }Posts
Posts are a blog content type:
- Title + slug (auto or manual)
- Lexical rich text
- Hero image
- Category (relationship)
- SEO tab (same as pages)
- Drafts with autosave + scheduled publishing
Posts are listed at /posts and rendered at /posts/[slug]. Editorial search across posts is wired via @payloadcms/plugin-search — kept separate from the per-tenant Orama index over records.
Categories
Tenant-scoped labels for organizing posts. Each category has a title and a slug. Assign to posts to enable filtered views.
Revalidation
When a page, post, tenant, or category is created or updated in the admin, the app automatically revalidates affected frontend routes. Changes appear without a manual redeploy or cache purge.