Content List Columns
A serif-headed content section with a two-column labeled-term list.
import type { Block } from 'payload'export const ContentListColumns: Block = { slug: 'contentListColumns', interfaceName: 'ContentListColumnsBlock', fields: [ { name: 'eyebrow', type: 'text', }, { name: 'title', type: 'text', required: true, }, { name: 'items', type: 'array', required: true, minRows: 2, maxRows: 6, admin: { initCollapsed: true, }, fields: [ { name: 'term', type: 'text', required: true, }, { name: 'description', type: 'textarea', required: true, }, ], }, ], labels: { plural: 'Content List Columns Blocks', singular: 'Content List Columns', },}import React from 'react'import type { ContentListColumnsBlock as ContentListColumnsBlockData } from '@/payload-types'import { Badge } from '@/components/ui/badge'import { cn } from '@/utilities/ui'type Props = ContentListColumnsBlockData & { id?: string className?: string disableInnerContainer?: boolean}export const ContentListColumnsBlock: React.FC<Props> = ({ className, disableInnerContainer, eyebrow, id, items, title,}) => { return ( <section className={cn('container', className)} id={id ? `block-${id}` : undefined}> <div className="overflow-hidden rounded-frame border border-border/70 bg-card/35 px-6 py-10 sm:px-8 lg:px-12 lg:py-14"> <div className={cn('flex flex-col gap-12', { 'mx-auto max-w-3xl': !disableInnerContainer, })} > <div className="flex flex-col gap-4"> {eyebrow ? ( <Badge variant="outline" className="w-fit rounded-full px-3 py-1 uppercase tracking-eyebrow"> {eyebrow} </Badge> ) : null} <h2 className="font-serif text-4xl font-medium text-balance">{title}</h2> </div> {items && items.length > 0 ? ( <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 sm:gap-12"> {items.map((item, index) => ( <p className="border-t border-border/70 pt-6 text-muted-foreground" key={item.id ?? `${item.term}-${index}`} > <span className="font-medium text-foreground">{item.term}</span> {item.description} </p> ))} </div> ) : null} </div> </div> </section> )}Installation
npx payload-components add content-list-columnsCopy the files straight from the registry, then wire the Payload fragments by hand:
pnpm dlx shadcn@latest add https://www.payload-components.xyz/r/content-list-columns.jsonWhat it installs
Copies 2 source files into your project:
src/blocks/ContentListColumns/config.tssrc/blocks/ContentListColumns/Component.tsx
…and makes 4 edits to wire the block into your project:
| Registers the block | src/collections/Pages/index.ts |
| Maps the renderer | src/blocks/RenderBlocks.tsx |
| Regenerates types | src/payload-types.ts |
| Regenerates the admin import map | src/app/(payload)/admin/importMap.js |
Re-running the install converges: it detects existing wiring, skips it, and records install state in .payload-components/state.json.
Content model
This serif "list" variant uses its own fields (not the shared contentFields base): a heading above a
two-column list of labeled-term paragraphs with top borders.
Prop
Type
Each item in items carries:
Prop
Type
Usage
ContentListColumns block to its layout.RenderBlocks on the frontend, fully typed — no extra wiring.Requirements
- Target
- payload-website-starter
- Payload
- v3
- Next.js
- 15 / 16
- shadcn UI
- badge
Your project must already expose components.json, src/payload.config.ts, src/blocks/RenderBlocks.tsx, src/collections/Pages/index.ts — the surfaces payload-components add patches. The CLI verifies this against the support matrix before touching anything.
In this family
content-columnscontent-image-leadcontent-feature-mediacontent-feature-splitcontent-showcasecontent-quotecontent-communitycontent-split-rowscontent-rowscontent-image-framecontent-statscontent-listcontent-list-columnscurrentcontent-list-icons