Entry points
Both packages straddle the server and client boundary, so each ships more than one entry. Importing from the wrong one is the most common wiring mistake.
@bison-lab/payload-blocks
Section titled “@bison-lab/payload-blocks”| Import | Contents | Runs where |
|---|---|---|
@bison-lab/payload-blocks |
Block configs, field builders, row types, resolveMedia, blockSamples, sampleImage |
Node. What payload.config.ts imports. Touches no React. |
@bison-lab/payload-blocks/react |
Renderers, RenderBlocks and BLOCK_ID_ATTRIBUTE, the image and link seams, resolveLink and ResolveLink, headerFromNavigation, headerItemsFromBlocks, the seam constants, the rendering types |
Client ("use client"). |
@bison-lab/payload-blocks/rich-text |
RichTextBlockRenderer, richTextBlockRenderer() to build one that resolves internal links, and internalDocToHrefFrom |
Client. Split out because it is the only thing that needs @payloadcms/richtext-lexical. |
@bison-lab/payload-blocks/admin |
MinRowsArrayField and LinkField, the admin fields the configs reference by path |
Client, inside the Payload admin. Resolved through the site’s import map, never imported by hand. |
The renderers are client components because the blocks they render are: every @bison-lab/ui export is a client reference, and the blocks are interactive anyway. That is also what makes imageComponent work. A Server Component can hand a client component reference across the boundary, but not a closure.
The admin entry is referenced by string, never imported: a config names MIN_ROWS_ARRAY_FIELD or LINK_FIELD (both exported from the main entry) as a field’s component, and payload generate:importmap turns the string into the import. A missing entry renders the field as nothing, not as the stock field.
@bison-lab/payload-core
Section titled “@bison-lab/payload-core”| Import | Contents | Runs where |
|---|---|---|
@bison-lab/payload-core |
seoPlugin, createTheme, createBrandAssets, createRoles, createFeatures, createPages, createUsers, createMedia, createAdminNav, adminNav, createNavigation, adminOnlyApiTab, predicates, noIndexField, SHARE_IMAGE_SIZE, firstImageIn, title and text helpers, types |
Node. What payload.config.ts imports; it loads the plugin. |
@bison-lab/payload-core/metadata |
pageMetadata, the title helpers, the same types |
Server. What a page route imports; it does not load the plugin. |
@bison-lab/payload-core/theme |
getPublishedTheme, themeHead |
Server. What a root layout imports; it does not load the plugin. |
@bison-lab/payload-core/navigation |
getNavigation, the Header and Footer slugs |
Server. What a site header imports; it does not load the plugin. |
Field builders
Section titled “Field builders”The main entry exports the builders the configs are made of, for a site’s own blocks:
imageField({ name, required, relationTo, admin })for a single upload from the media collection.linkFields({ required, pagesCollection })for a full link:label, the destination row, andnewTab.linkField({ name })is the same as one named group.linkDestinationFields()is the destination row alone:type,pageandhref, carryingLINK_FIELDso the editor picks a published page or pastes a URL in one box.pagesCollectionpoints a page link at a collection other thanpages.resolveLink(link)andlinkTypeOf(link)read a destination the way every renderer and the picker do, so a site’s own code agrees with them on every row, including rows from before links had atype.headingFields({ required })for the eyebrow, title and description every band opens with.emptyRows(n)andMIN_ROWS_ARRAY_FIELDfor an array that opens withnrows and will not go below them.resolveMedia(value)narrows an upload value, resolved or not, to{ src, alt, width, height }orundefined.
Generated types
Section titled “Generated types”Neither package can import a site’s payload-types, so every row shape is hand-written and structural: every field optional and nullable, no index signatures. A generated title: string is assignable to title?: string | null, never the reverse. Sites pass their generated types in, as BlockRegistryFor<AnyBlock> and seoPlugin<Page>() show.