Documentation

Installation

Install typed blocks in Payload CMS v3 with the Payload Components CLI. One command wires collection config, rendering, generated types, and the admin import map.

Use the Payload Components CLI to install a typed block in a supported Payload CMS v3 and Next.js App Router project. Run npx payload-components add <component> from the project root.

That command copies the block's source files and dependencies, then registers it in the Pages layout and RenderBlocks renderer. It runs generate:types and generate:importmap, then records the install in .payload-components/state.json.

If the admin cannot resolve a custom component path, use the Payload generate:importmap reference to check the command, generated output, path rules, and common fixes.

Requirements

The installer verifies the target project shape before it mutates anything. If a requirement is missing, it stops rather than leaving a half-wired repo.

Your project must run these majors:

DependencyVersion
payloadv3
nextv15 or v16

…and it must already contain the website-style block layout the installer patches into:

components.json
payload.config.ts
RenderBlocks.tsx
index.ts

Plus package.json scripts for generate:types and generate:importmap, which the CLI runs after wiring.

Install a component

Choose an installable block from the full component catalog, then run the block's add command from the root of your Payload project. Every component page shows its exact command; examples:

npx payload-components add hero-basic

Preview an install before making any changes:

npx payload-components add hero-basic --dry-run

The dry run performs the normal project and dependency validation, then lists the component files, RenderBlocks.tsx renderer mapping, Pages/index.ts block registration, dependencies, and generation commands. It does not write files, install packages, run commands, or update .payload-components/state.json.

Optional draft demo

Demo content is opt-in. Add --demo to a normal install to write a runnable TypeScript seed script strictly after the component install succeeds:

npx payload-components add hero-basic --demo
pnpm exec payload run payload-components/seed-hero-basic.ts

If the component is already installed, write the same script without rerunning the installer:

npx payload-components seed hero-basic
pnpm exec payload run payload-components/seed-hero-basic.ts

The first command only writes payload-components/seed-hero-basic.ts; it does not connect to your database. The CLI also prints the equivalent payload run command for npm, Yarn, Bun, or pnpm. Run that generated script yourself from the project root against the database you intend to modify.

The seed command fails closed

seed requires a current installed-state record, compatible dependencies, every manifest and registry-dependency file, and every Payload layout and renderer fragment before writing the script. If any check is incomplete or stale, it exits non-zero, reports why, and writes nothing. Fix the install with npx payload-components add hero-basic, then retry.

The generated demo stays in draft, records the exact Page and Media IDs it may touch, and refuses ambiguous same-slug content or missing private ownership state. Read the Payload CMS seed script guide for the ownership contract, retry behavior, access boundaries, and a project-owned seed example.

What the CLI does

The wrapper CLI owns the Payload-specific work that direct registry installation cannot handle:

Validate the target project shape — refuse to touch a repo that isn't a supported Payload v3 + Next.js project.

registry-build builds the checked-in manifest, then registry-add adds the registry item and installs its source files.

dependency-install installs missing component dependencies so the block compiles in your project.

fragment-apply registers the block in RenderBlocks and the Pages layout field.

post-install runs (generate:types, generate:importmap) and writes .payload-components/state.json.

When --demo is present, writing the demo script is a final sixth action after the installed state above. A failed install never writes a demo script.

Doctor

Run a read-only health check before or after installing components:

npx payload-components doctor

doctor validates the supported project shape, required post-install scripts, and recorded component installs in .payload-components/state.json. It exits non-zero when files, Payload fragments, dependency declarations, or install state need attention.

Already have a block file that is not appearing in the editor or on the page? Use the four-step Payload block troubleshooting checklist to match the symptom to the missing registration, render map, type, or import-map step.

TypeScript cannot resolve @/payload-types, or a new block interface is missing? Use the Payload 3 generated-types repair guide to check the output path, registration order, and generation command.

Want to see how one real block moves from config to the editor and frontend? Follow the hero-basic implementation from Block config through live rendering.

Idempotency

Running the same install twice should not duplicate imports, block registrations, or layout entries. The installer verifies files, fragments, dependencies, and recorded state before deciding whether any work is needed.

Direct registry installs

Every block is also published to a public, shadcn-compatible registry, so you can pull a block's files with the plain shadcn CLI — useful for inspecting a block or dropping one into a non-Payload project.

Register the namespace once in your project's components.json:

{
  "registries": {
    "@payload-components": "https://www.payload-components.xyz/r/{name}.json"
  }
}

Then add any block by name:

pnpm dlx shadcn@latest add @payload-components/hero-basic

Or install a single item straight from its URL, without configuring the namespace:

pnpm dlx shadcn@latest add https://www.payload-components.xyz/r/hero-basic.json

A direct shadcn add only copies the block's source files and its shadcn UI dependencies. It does not register the block in RenderBlocks, wire the Pages layout field, install Payload dependencies, or run generate:types and generate:importmap. For a real Payload project, use payload-components add — it does all of that and records install state.

On this page