payload API
Everything the package exports, by the path you import it from. Open an export for its signature and options.
@evolve-framework/payload
PayloadModule, the built-in content blocks and defineContentBlock for your own, and catalog page sync.
Classes
MapperRegistryRegistry of mappers keyed by Payload block slug (blockType).
import { MapperRegistry } from "@evolve-framework/payload";Blocks go through three channels. mapValue is the universal one: every block mapper
is reachable there by slug, and it is how a container maps its children
without importing the blocks that produce them. mapBlock and
mapColumnEntry are typed views over the two GraphQL unions, for fields whose
type is the union (a page body, a column) and which therefore need no
assertion at the call site. Page documents go through a fourth, mapPage,
keyed by page type id.
Registering a mapper for an already-known slug overrides the previous
registration without throwing. A block for other markets than the request's
maps to nothing in every channel but mapPage.
new MapperRegistry()| Method | Description |
|---|---|
registerBlock(slug: string, mapper: BlockMapper): MapperRegistry | |
registerColumnEntry(
slug: string,
mapper: ColumnEntryMapper,
): this | |
registerValue(slug: string, mapper: ContentBlockMapper): MapperRegistry | |
registerPage(pageType: string, mapper: PageMapper): MapperRegistry | |
hasBlock(slug: string): boolean | |
hasColumnEntry(slug: string): boolean | |
hasValue(slug: string): boolean | |
hasPage(pageType: string): boolean | |
mapBlock(
storeContext: StoreContext,
block: PayloadBlock,
): Block | undefined | |
mapColumnEntry(
storeContext: StoreContext,
block: PayloadBlock,
): ColumnEntry | undefined | |
mapValue<T>(
storeContext: StoreContext,
block: PayloadBlock,
): T | undefined | Map a child block by its blockType. |
mapPage(
pageType: string,
context: PageMapperContext,
doc: unknown,
): MappedPage | Map a document as the page type of this id. |
PayloadModuleModule wiring the Payload resolvers and typedefs into a Domain Service.
import { PayloadModule } from "@evolve-framework/payload";Unlike the Contentful and Storyblok modules this one speaks no HTTP to the
CMS: it boots Payload's Local API in-process and reads straight from the
database the admin app writes to. There is no delivery client, no API key and
no page cache to invalidate -- and no webhook route, because the
content-modified events are published by an afterChange hook running in
the admin process.
Only one PayloadModule instance per process is supported -- the Payload instance and the mapper registry are held as module-scope singletons.
Extends AbstractModule<PayloadLoaderContext>
new PayloadModule(options: PayloadModuleOptions)| Option | Type | Description |
|---|---|---|
config | SanitizedConfig | Promise<SanitizedConfig> | The project's payload config -- the very same module the admin app loads.
Import it directly ( |
articlesPerProduct? | number | How many articles a product shows at most. Defaults to 4. |
blocks? | ContentBlockDef[] | The complete set of content blocks the module serves. Defaults to the
built-in MorePass the same array you passed to |
locales? | LocaleMap | Maps store-context locales ( |
homePath? | string | Path the site root is stored under. Frontends ask for the root with an empty path; this is what that resolves to. Defaults to "homepage". |
multiTenant? | boolean | Whether the config is tenant-scoped, i.e. whether reads must match the
request's |
tenants? | TenantMap | Maps store keys onto tenant slugs, for stores that share a tenant or whose tenant is named differently. A store missing from it reads the tenant whose slug is its store key. When set, catalog pages are kept in the mapped tenants only; when not, in every tenant. |
mappers? | ((registry: MapperRegistry) => void) | Optional callback invoked with the pre-populated MapperRegistry. Use it to add or override mappers for custom Payload blocks. |
StoreContextThe store, locale and currency a request is for.
import { StoreContext } from "@evolve-framework/payload";new StoreContext(storeContext: StoreContextInput)| Option | Type | Description |
|---|---|---|
currency | string | The currency used in the store context. |
locale | string | The locale of the store context. For example: en-US. |
storeKey | string | The store key associated with the store context. |
country? | InputMaybe<string> | The market the store context is for; leave out for every market. |
Functions
defineContentBlockDefines a content block.
import { defineContentBlock } from "@evolve-framework/payload";mapper: (context, block: PayloadPromoList): PromoList => ({ ... })
Children are mapped through context.mapValue<T>(child) -- never by
importing another block.
The output type is erased on the way out, because a block is meant to be
reached through the registry rather than called directly -- that is what lets
a container map its children without importing them. Dispatch through
mapBlock / mapColumnEntry / mapValue to get a typed result back.
function defineContentBlock<TBlock, TOutput>( config: { id: string; typename: string; typeDefs?: string | undefined; payload?: Block | undefined; groups?: string[] | undefined; slots?: Record<string, Slot> | undefined; mapper: (context: MapperContext, block: TBlock) => TOutput; },): ContentBlockDef & { mapper: ContentBlockMapper;}| Option | Type | Description |
|---|---|---|
id | string | |
typename | string | |
mapper | (context: MapperContext, block: TBlock) => TOutput | |
typeDefs? | string | |
payload? | Block | |
groups? | string[] | |
slots? | Record<string, Slot> |
Returns ContentBlockDef & { mapper: ContentBlockMapper; }
deleteCatalogPageRemove the catalog page for a deleted category from every tenant.
import { deleteCatalogPage } from "@evolve-framework/payload";A category that no longer exists lists nothing, so the page would render an empty grid on a route the storefront still advertises. Deleting it is the honest outcome — and it is why the engine's fields are kept separable: there is no editor-authored content here that this is entitled to destroy beyond the page the engine created.
function deleteCatalogPage(categoryId: string): Promise<boolean>Returns Promise<boolean>
getMapperRegistryThe registry PayloadModule configured; throws before it has.
import { getMapperRegistry } from "@evolve-framework/payload";function getMapperRegistry(): MapperRegistryReturns MapperRegistry
getPayloadInstanceThe Payload instance PayloadModule booted; throws before it has.
import { getPayloadInstance } from "@evolve-framework/payload";function getPayloadInstance(): BasePayloadReturns Payload
mapAssetMap a Payload media document onto the shared ContentAsset.
import { mapAsset } from "@evolve-framework/payload";ContentAsset has no url field -- the other two CMS packages put the full
CDN url in filename (Storyblok's filename is the url), so we do the
same with Payload's url and keep the frontend contract identical. See the
masterplan's open question on adding url to the shared type.
function mapAsset(media: MediaRelation): ContentAsset | undefinedReturns ContentAsset | undefined
mapBlocksMap a blocks field onto the Block union, dropping anything the registry has no mapper for (it is logged there), and any block whose mapper throws, so that one malformed block cannot fail the page or listing it is part of.
import { mapBlocks } from "@evolve-framework/payload";A block registered only as a column entry is answered as Columns holding
that one entry, so column content (an image, an FAQ) can be dropped straight
into a page body without the editor having to reach for a layout block first. Rich text is a
block of its own and is answered as it is. The blocks a snippet places are
mapped as the body's own.
function mapBlocks( blocks: PayloadBlock[] | undefined, storeContext: StoreContext, source?: string,): Block[]Returns Block[]
mapBlockSettingsThe settings every block of the content model carries: the anchor an in-page link points to, and who the block is shown to, everyone where unset.
import { mapBlockSettings } from "@evolve-framework/payload";function mapBlockSettings( block: { anchor?: string | null | undefined; audience?: string | null | undefined; },): { anchor: string | undefined; audience: AudienceType;}| Option | Type | Description |
|---|---|---|
anchor? | string | null | |
audience? | string | null |
Returns { anchor: string | undefined; audience: AudienceType; }
mapCategoriesA categories field as the categories the commerce subgraph resolves by key.
import { mapCategories } from "@evolve-framework/payload";function mapCategories( keys: (string | null)[] | null | undefined,): ProductCategory[]Returns ProductCategory[]
mapContentPageA content_page document as ContentPage, by its registered page mapper.
import { mapContentPage } from "@evolve-framework/payload";function mapContentPage( doc: PayloadPage, storeContext: StoreContext,): ContentPage| Option | Type | Description |
|---|---|---|
id | string | number | |
name? | string | |
path? | string | |
seoTitle? | string | null | |
seoDescription? | string | null | |
seoImage? | MediaRelation | |
intro? | string | null | |
leadImage? | MediaRelation | |
body? | PayloadBlock[] | null | |
categories? | string[] | null | |
headingVisible? | boolean | null | |
createdAt? | string |
Returns ContentPage
mapLinkMap a link group onto the shared ResourceLink.
import { mapLink } from "@evolve-framework/payload";type is normalized onto the shared ResourceLinkType, which frontends
switch on to decide how to build the href. value carries the target in the
form that type implies -- a path for content and catalog links, a slug for
products, the URL for external ones.
function mapLink(link: PayloadLink | undefined): ResourceLink| Option | Type | Description |
|---|---|---|
type? | string | null | |
name? | string | null | |
page? | PageRelation | |
catalogPage? | PageRelation | |
path? | string | null | Raw path, for targets that are not documents in this CMS. |
product? | string | null | |
url? | string | null | |
asset? | MediaRelation | |
anchor? | string | null | |
newTab? | boolean | null |
Returns ResourceLink
mapLinkListMap a link list, dropping rows the editor added but never filled in.
import { mapLinkList } from "@evolve-framework/payload";function mapLinkList(rows: PayloadLinkRow[] | undefined): ResourceLink[]Returns ResourceLink[]
mapLinkValueMap a link group onto Link.
import { mapLinkValue } from "@evolve-framework/payload";function mapLinkValue( link: PayloadLinkValue | null | undefined,): MappedLink | undefined| Option | Type | Description |
|---|---|---|
label? | string | null | |
page? | PageRelation | |
product? | string | null | |
route? | string | null | |
url? | string | null | |
variant? | string | null |
Returns MappedLink | undefined
mapOptionalLinkOptional variant: an untouched link group maps to nothing rather than to an empty link.
import { mapOptionalLink } from "@evolve-framework/payload";Emptiness is judged on the target, not on type -- Payload applies the
type default to every group whether or not the editor ever opened it, so a
type on its own says nothing.
function mapOptionalLink( link: PayloadLink | undefined,): ResourceLink | undefined| Option | Type | Description |
|---|---|---|
type? | string | null | |
name? | string | null | |
page? | PageRelation | |
catalogPage? | PageRelation | |
path? | string | null | Raw path, for targets that are not documents in this CMS. |
product? | string | null | |
url? | string | null | |
asset? | MediaRelation | |
anchor? | string | null | |
newTab? | boolean | null |
Returns ResourceLink | undefined
mapPageMetaA page's metadata from its three SEO fields, the image falling back to the lead image.
import { mapPageMeta } from "@evolve-framework/payload";function mapPageMeta( doc: { seoTitle?: string | null | undefined; seoDescription?: string | null | undefined; seoImage?: MediaRelation; }, fallbackImage?: MediaRelation,): PageMeta | undefined| Option | Type | Description |
|---|---|---|
seoTitle? | string | null | |
seoDescription? | string | null | |
seoImage? | MediaRelation |
Returns PageMeta | undefined
mapProductSourceA stored product source, or undefined where it names no category, filters or sort.
import { mapProductSource } from "@evolve-framework/payload";function mapProductSource( doc: PayloadProductSource, fallbackFilters?: readonly FacetFilter[],): ProductSource | undefined| Option | Type | Description |
|---|---|---|
category? | string | null | |
filters? | string | null | |
sort? | string | null |
Returns ProductSource | undefined
mapPromoMap a promo onto Promo; one without a title is no promo.
import { mapPromo } from "@evolve-framework/payload";function mapPromo( promo: PayloadPromo | null | undefined, fallbackId: string,): MappedPromo | undefined| Option | Type | Description |
|---|---|---|
id? | string | null | |
title? | string | null | |
text? | string | null | |
image? | MediaRelation | |
link? | PayloadLinkValue | null |
Returns MappedPromo | undefined
mapPromosMap a list of promos, leaving out the rows without a title.
import { mapPromos } from "@evolve-framework/payload";function mapPromos( promos: PayloadPromo[] | null | undefined, parentId: string,): MappedPromo[]Returns MappedPromo[]
mapRichTextA Lexical document as rich text: the vendor-neutral tree, with each block placed in the text mapped through the registry as the embed that wraps it.
import { mapRichText } from "@evolve-framework/payload";function mapRichText( context: Pick<MapperContext, "mapValue">, id: string, document: unknown,): RichText| Option | Type | Description |
|---|---|---|
mapValue | <T>(block: PayloadBlock) => T | undefined | Map a child block by its |
Returns RichText
mapUspsMap selling points onto Usp, leaving out a row without text.
import { mapUsps } from "@evolve-framework/payload";function mapUsps(usps: PayloadUsp[] | null | undefined, parentId: string): Usp[]Returns Usp[]
normalizePathNormalise a requested page path to the stored form.
import { normalizePath } from "@evolve-framework/payload";The empty path and / both mean the root and resolve to the configured home
path. Everything else keeps its segments and gains a leading slash, so an
editor sees /contact rather than contact.
function normalizePath(path: string): stringReturns string
registerBlocksRegisters each block's mapper into the registry.
import { registerBlocks } from "@evolve-framework/payload";A page type's mapper goes into the page channel instead. Blocks without either (layout wrappers, bare union declarations) are assembled by their resolver and skipped.
function registerBlocks( registry: MapperRegistry, blocks: ContentBlockDef[],): voidReturns void
scopedWhereCombine a lookup constraint with the tenant constraint.
import { scopedWhere } from "@evolve-framework/payload";Every read goes through here: forgetting it would silently serve another store's content, which is the one failure mode of a shared database that no test of a single tenant can catch.
function scopedWhere(storeContext: StoreContext, ...constraints: Where[]): WhereReturns Where
tenantWhereThe tenant constraint for a request, as a where fragment.
import { tenantWhere } from "@evolve-framework/payload";The multi-tenant plugin adds a tenant relationship to every scoped
collection; matching on tenant.slug means a read needs no tenant lookup of
its own.
Returns nothing when tenancy is off, so callers can spread it either way.
function tenantWhere(storeContext: StoreContext): Where[]Returns Where[]
toAudienceA stored audience as AudienceType; EVERYONE when unset or unknown.
import { toAudience } from "@evolve-framework/payload";function toAudience(value: string | undefined): AudienceTypeReturns AudienceType
toCatalogPageLayoutA stored catalog page layout as CatalogPageLayoutType, or fallback.
import { toCatalogPageLayout } from "@evolve-framework/payload";function toCatalogPageLayout( value: string | undefined, fallback: CatalogPageLayoutType,): CatalogPageLayoutTypeReturns CatalogPageLayoutType
toColumnsRatioA stored columns ratio as ColumnsRatioType, or fallback.
import { toColumnsRatio } from "@evolve-framework/payload";function toColumnsRatio( value: string | undefined, fallback: ColumnsRatioType,): ColumnsRatioTypeReturns ColumnsRatioType
toPayloadLocaleMap the store context locale onto a Payload locale code.
import { toPayloadLocale } from "@evolve-framework/payload";storeContext.locale is a full BCP-47 tag (nl-NL); Payload locale codes are
whatever the project config declares, commonly just the language subtag. The
default strips the region; pass an explicit map to the module when the project
uses something else.
function toPayloadLocale(locale: string): stringReturns string
toResourceLinkTypeA stored link type as ResourceLinkType, or fallback.
import { toResourceLinkType } from "@evolve-framework/payload";function toResourceLinkType( value: string | undefined, fallback: ResourceLinkType,): ResourceLinkTypeReturns ResourceLinkType
upsertCatalogPageCreate the catalog page for a category in every tenant, or refresh the fields the engine owns on the ones that already exist.
import { upsertCatalogPage } from "@evolve-framework/payload";Returns created when any tenant gained a page, so a backfill can report
rather than guess.
function upsertCatalogPage( input: CatalogPageInput,): Promise<"created" | "updated">| Option | Type | Description |
|---|---|---|
categoryId | string | The commerce engine's category id. The join key, and the natural key. |
name | Record<string, string> | Category name per store locale, e.g. |
path | string | Record<string, string> | The path the storefront routes. MorePer store locale where the engine translates its slugs — |
categoryKey? | string | The category's key, which the page's product source refers to. |
parentCategoryId? | string | The parent category's id, whose catalog page becomes this page's parent. Absent for a root category. |
Returns Promise<"created" | "updated">
Constants
blocksBuilt-in content blocks keyed by their Payload block slug.
import { blocks } from "@evolve-framework/payload";const blocks: Record<string, ContentBlockDef>BODY_BLOCKSWhat a page body accepts: every block, and rich text of its own.
import { BODY_BLOCKS } from "@evolve-framework/payload";const BODY_BLOCKS: SlotAcceptscontentBlocksBuilt-in content blocks.
import { contentBlocks } from "@evolve-framework/payload";const contentBlocks: ContentBlockDef[]pageTypesThe built-in page types.
import { pageTypes } from "@evolve-framework/payload";const pageTypes: ContentBlockDef[]SNIPPET_BODY_BLOCKSWhat a content snippet's body accepts: a page body's blocks, but no snippet.
import { SNIPPET_BODY_BLOCKS } from "@evolve-framework/payload";const SNIPPET_BODY_BLOCKS: SlotAcceptsTypes
BlockMapperMaps a stored block onto a Block, or undefined to leave it out.
import { type BlockMapper } from "@evolve-framework/payload";export type BlockMapper = (context: MapperContext, block: PayloadBlock) => Block | undefined;ColumnEntryMapperMaps a stored block onto a ColumnEntry, or undefined to leave it out.
import { type ColumnEntryMapper } from "@evolve-framework/payload";export type ColumnEntryMapper = (context: MapperContext, block: PayloadBlock) => ColumnEntry | undefined;ContentBlockDefA content block bundles everything one Payload block needs: its output typename, SDL fragment, mapper (Payload block -> GraphQL type), the Payload field config that defines it, and its composition metadata (which groups it belongs to, and which slots it exposes).
import { type ContentBlockDef } from "@evolve-framework/payload";A block references other blocks only by slug or group -- never by import --
so any one can be ejected while still referencing the rest. A container maps
its children by dispatching them through the registry on their blockType,
so each block owns the mapping of its own type and nothing else.
export type ContentBlockDef = { id: string; typename: string; typeDefs?: string; payload?: Block; groups?: GroupId[]; slots?: Record<string, Slot>; mapper?: ContentBlockMapper; pageMapper?: PageMapper;};ContentBlockMapperThe registry-facing mapper: takes an untyped block and returns whatever the block's GraphQL type is.
import { type ContentBlockMapper } from "@evolve-framework/payload";export type ContentBlockMapper = (context: MapperContext, block: PayloadBlock) => unknown;ContextValueThe GraphQL context the resolvers of this package read.
import { type ContextValue } from "@evolve-framework/payload";export type ContextValue = { storeContext: StoreContext; loaders: { articlesByCategoryTrail: DataLoader<string, TaggedDocument[]>; };};GroupIdA slot-group: a named set of blocks that can fill a slot.
import { type GroupId } from "@evolve-framework/payload";export type GroupId = string;LocaleMapStore-context locales (nl-NL) mapped onto Payload locale codes.
import { type LocaleMap } from "@evolve-framework/payload";export type LocaleMap = Record<string, string>;MappedLinkA Link before its page is mapped: the page's collection and document travel along, and the Link.page field resolver maps them, since a block cannot import the page mappers.
import { type MappedLink } from "@evolve-framework/payload";export type MappedLink = Omit<Link, "page"> & { pageRef?: { collection: string; doc: object; };};MappedPageEach concrete page type, so a page mapper can return any of them.
import { type MappedPage } from "@evolve-framework/payload";export type MappedPage = ArticleOverviewPage | ArticlePage | CatalogPage | ContentPage;MappedPromoA Promo whose link names its page by reference, not resolved yet.
import { type MappedPromo } from "@evolve-framework/payload";export type MappedPromo = Omit<Promo, "link"> & { link?: MappedLink;};MediaRelationAn upload field as read: the media document, its id, or nothing.
import { type MediaRelation } from "@evolve-framework/payload";export type MediaRelation = PayloadMedia | string | null | undefined;PageMapperMaps a document of a page type's collection onto its GraphQL page.
import { type PageMapper } from "@evolve-framework/payload";export type PageMapper = (context: PageMapperContext, doc: unknown) => MappedPage;PageMapperContextWhat a page mapper is handed: a mapper's context, plus what a page needs for its blocks fields and the pages it links to.
import { type PageMapperContext } from "@evolve-framework/payload";export type PageMapperContext = MapperContext & { mapBlocks: (blocks: PayloadBlock[] | null | undefined, source: string | undefined) => Block$1[]; mapSingle: <T>(blocks: PayloadBlock[] | null | undefined, source: string | undefined) => T | undefined; mapPage: <T extends MappedPage>(pageType: string, doc: unknown) => T;};PayloadArticleOverviewPageAn article_overview_page document as returned by the Local API.
import { type PayloadArticleOverviewPage } from "@evolve-framework/payload";export type PayloadArticleOverviewPage = PayloadPage & { heading?: string | null; intro?: string | null; featured?: PayloadArticlePage | string | number | null;};PayloadArticlePageAn article_page document as returned by the Local API.
import { type PayloadArticlePage } from "@evolve-framework/payload";export type PayloadArticlePage = PayloadPage & { title?: string | null; lead?: string | null; leadImage?: MediaRelation; publishedAt?: string | null; author?: PayloadAuthor | string | number | null; topics?: (PayloadTopic | string | number)[] | null; categories?: string[] | null; parent?: PayloadArticleOverviewPage | string | number | null; related?: (PayloadArticlePage | string | number)[] | null;};PayloadAuthorAn author document as returned by the Local API.
import { type PayloadAuthor } from "@evolve-framework/payload";export type PayloadAuthor = { id: string | number; name?: string | null; role?: string | null; photo?: MediaRelation; bio?: string | null;};PayloadBlockThe shape every raw Payload block shares.
import { type PayloadBlock } from "@evolve-framework/payload";export type PayloadBlock = { blockType: string; id?: string; [key: string]: unknown;};PayloadCatalogPageA catalog_page document as returned by the Local API.
import { type PayloadCatalogPage } from "@evolve-framework/payload";export type PayloadCatalogPage = Omit<PayloadPage, "body"> & PayloadProductSource & { categoryId?: string | null; layout?: string | null; facetFilters?: { key?: string | null; values?: string[] | null; }[] | null; topContent?: PayloadBlock[] | null; bottomContent?: PayloadBlock[] | null; promos?: PayloadPromo[] | null;};PayloadLinkA populated link group, as produced by config/fields/link.ts.
import { type PayloadLink } from "@evolve-framework/payload";export type PayloadLink = { type?: string | null; name?: string | null; page?: PageRelation; catalogPage?: PageRelation; path?: string | null; product?: string | null; url?: string | null; asset?: MediaRelation; anchor?: string | null; newTab?: boolean | null;};PayloadLinkRowOne row of a linkListField array.
import { type PayloadLinkRow } from "@evolve-framework/payload";export type PayloadLinkRow = { link?: PayloadLink;};PayloadLinkValueA link group, as produced by config/fields/link-value.ts.
import { type PayloadLinkValue } from "@evolve-framework/payload";export type PayloadLinkValue = { label?: string | null; page?: PageRelation; product?: string | null; route?: string | null; url?: string | null; variant?: string | null;};PayloadPageA content_page document as returned by the Local API.
import { type PayloadPage } from "@evolve-framework/payload";export type PayloadPage = { id: string | number; name?: string; path?: string; seoTitle?: string | null; seoDescription?: string | null; seoImage?: MediaRelation; intro?: string | null; leadImage?: MediaRelation; body?: PayloadBlock[] | null; categories?: string[] | null; headingVisible?: boolean | null; createdAt?: string;};PayloadProductSourceThe fields productSourceFields stores a product source in.
import { type PayloadProductSource } from "@evolve-framework/payload";export type PayloadProductSource = { category?: string | null; filters?: string | null; sort?: string | null;};PayloadPromoA promo as stored: an array row, or a group in a menu entry.
import { type PayloadPromo } from "@evolve-framework/payload";export type PayloadPromo = { id?: string | null; title?: string | null; text?: string | null; image?: MediaRelation; link?: PayloadLinkValue | null;};PayloadTopicA topic document as returned by the Local API.
import { type PayloadTopic } from "@evolve-framework/payload";export type PayloadTopic = { id: string | number; name?: string | null; slug?: string | null; description?: string | null; leadImage?: MediaRelation;};PayloadUspA selling point as stored: an array row of the site or a usp_list.
import { type PayloadUsp } from "@evolve-framework/payload";export type PayloadUsp = { id?: string | null; text?: string | null; description?: string | null; icon?: string | null; link?: PayloadLinkValue | null;};PlacedBlocksBlocks a mapper places where it stands, as snippet places a content snippet's: mapBlocks maps them as the surrounding body's own, so the storefront never sees the wrapper.
import { type PlacedBlocks } from "@evolve-framework/payload";export type PlacedBlocks = { __typename: "PlacedBlocks"; source: string | undefined; blocks: PayloadBlock[];};SlotA named containment point a block exposes.
import { type Slot } from "@evolve-framework/payload";export type Slot = { accepts: SlotAccepts;};SlotAcceptsWhat a slot accepts.
import { type SlotAccepts } from "@evolve-framework/payload";export type SlotAccepts = GroupId | { group?: GroupId; ids?: string[]; exclude?: string[];};TenantMapMaps store keys onto tenant slugs.
import { type TenantMap } from "@evolve-framework/payload";export type TenantMap = Record<string, string>;@evolve-framework/payload/config
evolveCms, the Payload plugin with the pages and media collections, multi-tenancy by store and the catalog pickers, plus the collections on their own.
Functions
applySlotReferencesFill in blockReferences on every field whose name matches a declared slot.
import { applySlotReferences } from "@evolve-framework/payload/config";A block declares its containment points once, in slots; the field config
writes blockReferences: [] and this fills it. Keeping the slot declaration
as the single source of truth is what makes groups: ["block"] sufficient to
make a new block droppable into a page body -- the same property the
Terraform whitelist gives the other two CMS packages. Fields inside tabs are
filled too, so it applies before or after withFieldTabs.
function applySlotReferences( fields: Field[], slots: Record<string, Slot> | undefined, blocks: ContentBlockDef[],): Field[]Returns Field[]
blockSettingsFieldsThe fields every block of the content model carries, on its Settings tab: the anchor an in-page link or the table of contents points to, who the block is shown to, and the markets it is shown in.
import { blockSettingsFields } from "@evolve-framework/payload/config";function blockSettingsFields(): Field[]Returns Field[]
contentPageCollectionThe content_page collection backing ContentPage.
import { contentPageCollection } from "@evolve-framework/payload/config";Unlike Storyblok and Contentful -- where a page is a component/content type
like any other -- a Payload page is a collection. The content_page block def
still declares the slots (body); this reads them so a block that
declares groups: ["block"] becomes droppable into a page body with no
further wiring, the same property the Terraform whitelist gives the other two
CMS packages.
path is derived from slug and parent per locale, and stored so a page
is found by one query on it; one read with locale: "all" yields every
locale's path.
function contentPageCollection(blocks: ContentBlockDef[]): CollectionConfigReturns CollectionConfig
createGatewayCatalogThe picker callbacks for a project, ready to hand to evolveCms.
import { createGatewayCatalog } from "@evolve-framework/payload/config";Returns CatalogOptions minus components, which stay a project's own —
they have to be bound to Payload's form state in the admin app.
function createGatewayCatalog( options: GatewayCatalogOptions,): Omit<CatalogOptions, "components">| Option | Type | Description |
|---|---|---|
endpoint | string | Where the graph is, e.g. |
storeContext | { storeKey: string; locale: string; currency: string; } | The store an editor authors for. MoreFixed rather than per-request: an admin is one editor looking at one
store's catalogue. A deployment serving several would vary it by tenant,
which is what |
categoryLookupLimit? | number | How many categories to scan when resolving one by id. MoreThe contract has no lookup by id — only by search term and by path — so
this walks the list. Fine for a catalogue of ordinary size and wrong for a
very large one, where a category past the cap resolves to nothing and an
editor sees a bare id. The real fix is a |
Returns Omit<CatalogOptions, "components">
defineContentBlockDefines a content block.
import { defineContentBlock } from "@evolve-framework/payload/config";mapper: (context, block: PayloadPromoList): PromoList => ({ ... })
Children are mapped through context.mapValue<T>(child) -- never by
importing another block.
The output type is erased on the way out, because a block is meant to be
reached through the registry rather than called directly -- that is what lets
a container map its children without importing them. Dispatch through
mapBlock / mapColumnEntry / mapValue to get a typed result back.
function defineContentBlock<TBlock, TOutput>( config: { id: string; typename: string; typeDefs?: string | undefined; payload?: Block | undefined; groups?: string[] | undefined; slots?: Record<string, Slot> | undefined; mapper: (context: MapperContext, block: TBlock) => TOutput; },): ContentBlockDef & { mapper: ContentBlockMapper;}| Option | Type | Description |
|---|---|---|
id | string | |
typename | string | |
mapper | (context: MapperContext, block: TBlock) => TOutput | |
typeDefs? | string | |
payload? | Block | |
groups? | string[] | |
slots? | Record<string, Slot> |
Returns ContentBlockDef & { mapper: ContentBlockMapper; }
evolveCmsThe Payload plugin that installs everything Evolve's CMS subgraph expects: the block configs (into config.blocks, so slots can reference them by slug) and the collections that back the content types.
import { evolveCms } from "@evolve-framework/payload/config";This runs inside the Payload process -- the admin app and any migration job.
It must not import runtime service code from @evolve-framework/core.
function evolveCms(options?: EvolveCmsOptions | undefined): Plugin[]| Option | Type | Description |
|---|---|---|
blocks? | ContentBlockDef[] | The complete set of content blocks to register. Defaults to the built-in
MorePass the same array to |
collections? | boolean | Whether to register the built-in collections ( |
media? | MediaOptions | Options for the built-in |
multiTenant? | boolean | Scope every content collection to a tenant, where a tenant is a content space of its own, the way a separate Storyblok space is. MoreEvery request into the subgraph carries a store context, and the resolvers
match documents on the tenant its Defaults to true. |
catalog? | CatalogOptions | Where the catalogue pickers read from. MoreSupplying these turns the commerce identifier fields — a variant's sku, a product's slug, a category's id — from free text into pickers, and adds the admin routes they call. Leave it out and those fields stay plain text, which is the correct behaviour for a project that has not wired a commerce backend into its admin. |
users? | boolean | Whether to provide a bare auth-enabled MoreDefaults to true. |
contentEvents? | ContentEventsOptions | Publish a |
keyPatterns? | Partial<Record<"sku" | "category" | "categoryKey" | "brand", string | RegExp>> | The format of each commerce key an editor types, such as a SKU, as this project's commerce backend writes it. Unset, a key only may not contain whitespace. |
markets? | string[] | The countries the store sells in, as ISO 3166-1 alpha-2 codes, which an editor can limit a page or a block to. A request's store context names its market; content for other markets is left out of it. Unset, no content can be limited to a market. |
Returns Plugin[]
keysValidationkeyValidation for a hasMany text field, checking every key.
import { keysValidation } from "@evolve-framework/payload/config";function keysValidation( kind: "sku" | "category" | "categoryKey" | "brand",): TextFieldManyValidationReturns TextFieldManyValidation
keyValidationValidation for a text field holding a commerce key: Payload's own text checks first, required among them, then the project's pattern for that kind of key.
import { keyValidation } from "@evolve-framework/payload/config";function keyValidation( kind: "sku" | "category" | "categoryKey" | "brand",): TextFieldSingleValidationReturns TextFieldSingleValidation
linkFieldThe ResourceLink field.
import { linkField } from "@evolve-framework/payload/config";type mirrors the shared ResourceLinkType enum, because frontends switch on
it to build the href -- a link typed external where the storefront expects
content renders as no link at all. Each type has its own target field and
the admin UI hides the rest.
Shipped as a factory rather than a constant because blocks need it under
different names (link, viewMoreLink) and requiredness.
function linkField(options?: LinkFieldOptions | undefined): Field| Option | Type | Description |
|---|---|---|
name? | string | Field name. Defaults to "link". |
required? | boolean | Whether the editor must fill in a target for the chosen type. |
label? | string | Label shown in the admin UI. |
Returns Field
linkListFieldA repeatable list of links (top bar, socials, payment methods, ...).
import { linkListField } from "@evolve-framework/payload/config";Each row wraps a link group rather than flattening its fields, so the same
mapLink handles a single link and a list entry alike.
function linkListField(name: string, label?: string | undefined): FieldReturns Field
linkValueFieldThe Link value object: a label and exactly one target, a page, a product by its sku, a storefront route or a URL, drawn as a primary or a secondary call to action.
import { linkValueField } from "@evolve-framework/payload/config";function linkValueField(options?: LinkValueOptions | undefined): Field| Option | Type | Description |
|---|---|---|
name? | string | Field name. Defaults to "link". |
required? | boolean | Whether the link must point somewhere. |
label? | string | Label shown in the admin UI. |
Returns Field
marketsFieldThe markets field: country codes the content is limited to, empty for every market.
import { marketsField } from "@evolve-framework/payload/config";function marketsField(description: string): FieldReturns Field
mediaCollectionUploads.
import { mediaCollection } from "@evolve-framework/payload/config";For anything beyond local development, add @payloadcms/storage-s3 (or
-azure, -gcs) in the project config; a container's local disk is not a place
to keep uploads.
function mediaCollection(options?: MediaOptions | undefined): CollectionConfig| Option | Type | Description |
|---|---|---|
staticDir? | string | Absolute directory uploads are written to and read from. MorePayload defaults this to |
Returns CollectionConfig
pagePathFieldsThe slug, parent and path fields of a page collection.
import { pagePathFields } from "@evolve-framework/payload/config";function pagePathFields( collection: PageCollection, parent: { required?: boolean | undefined; description: string; },): Field[]| Option | Type | Description |
|---|---|---|
description | string | |
required? | boolean |
Returns Field[]
pagePathHooksThe hooks that keep a page collection's paths derived, and that redirect a published page's old path to it when the path changes.
import { pagePathHooks } from "@evolve-framework/payload/config";function pagePathHooks( collection: PageCollection,): { beforeChange: CollectionBeforeChangeHook[]; afterChange: CollectionAfterChangeHook[];}Returns { beforeChange: CollectionBeforeChangeHook[]; afterChange: CollectionAfterChangeHook[]; }
payloadBlocksThe block configs registered into config.blocks, with every slot resolved and every field on its tab.
import { payloadBlocks } from "@evolve-framework/payload/config";function payloadBlocks(blocks: ContentBlockDef[]): Block[]Returns Block[]
productSourceFieldsThe fields a product source is stored in, shared by the catalog page and the product list: a category key, the filters pasted from a storefront URL, and a sort order.
import { productSourceFields } from "@evolve-framework/payload/config";function productSourceFields(): Field[]Returns Field[]
promoFieldsThe fields of the Promo value object: a card with a title, a short text, an image and the link it leads to.
import { promoFields } from "@evolve-framework/payload/config";function promoFields( options?: { optional?: boolean | undefined; },): Field[]| Option | Type | Description |
|---|---|---|
optional? | boolean |
Returns Field[]
readPublishedRead access for a collection with drafts: a logged-in user reads everything, anyone else only published documents.
import { readPublished } from "@evolve-framework/payload/config";function readPublished( args: AccessArgs<any>,): AccessResult | Promise<AccessResult>Returns AccessResult | Promise<AccessResult>
resolveSlotResolve what a slot accepts into a concrete list of Payload block slugs: the slot's explicit ids plus every block declaring the accepted group, less the ids it excludes.
import { resolveSlot } from "@evolve-framework/payload/config";This is the Payload counterpart of Storyblok's generated
component_whitelist local -- same derivation from groups, but the output
is a TS array assembled at import time rather than HCL written to disk.
function resolveSlot(slot: Slot, blocks: ContentBlockDef[]): string[]| Option | Type | Description |
|---|---|---|
accepts | SlotAccepts |
Returns string[]
uspFieldsThe fields of the Usp value object: a selling point, an optional second line and icon, and where it leads.
import { uspFields } from "@evolve-framework/payload/config";function uspFields(): Field[]Returns Field[]
withFieldTabsA content type's fields on the Content, SEO and Settings tabs, by the rule every CMS shares.
import { withFieldTabs } from "@evolve-framework/payload/config";function withFieldTabs(fields: Field[]): Field[]Returns Field[]
Constants
blocksBuilt-in content blocks keyed by their Payload block slug.
import { blocks } from "@evolve-framework/payload/config";const blocks: Record<string, ContentBlockDef>CONTENT_MODIFIED_TASKThe task that publishes a queued event.
import { CONTENT_MODIFIED_TASK } from "@evolve-framework/payload/config";const CONTENT_MODIFIED_TASK: "evolve-content-modified"contentBlocksBuilt-in content blocks.
import { contentBlocks } from "@evolve-framework/payload/config";const contentBlocks: ContentBlockDef[]PAGE_RELATIONSThe collections a link may open, one per page type.
import { PAGE_RELATIONS } from "@evolve-framework/payload/config";const PAGE_RELATIONS: string[]Types
CatalogCategoryOne category in the search list.
import { type CatalogCategory } from "@evolve-framework/payload/config";export type CatalogCategory = { id: string; name: string; path?: string; ancestors?: string[];};CatalogOptionsThe catalog lookups behind the product, variant and category pickers.
import { type CatalogOptions } from "@evolve-framework/payload/config";export type CatalogOptions = { searchProducts?: (term: string) => Promise<CatalogProduct[]>; variantSelector?: (slug: string, selectedSku?: string) => Promise<CatalogVariantSelector | undefined>; productForSku?: (sku: string) => Promise<CatalogProduct | undefined>; searchCategories?: (term: string) => Promise<CatalogCategory[]>; categoryById?: (id: string) => Promise<CatalogCategory | undefined>; components?: { variant?: string; product?: string; category?: string; variantRowLabel?: string; };};CatalogProductOne product in the search list.
import { type CatalogProduct } from "@evolve-framework/payload/config";export type CatalogProduct = { slug: string; name: string; image?: string;};CatalogVariantDimensionA dimension a product varies along, e.g.
import { type CatalogVariantDimension } from "@evolve-framework/payload/config";export type CatalogVariantDimension = { name: string; label: string; options: CatalogVariantOption[];};CatalogVariantOptionOne choice within a dimension, and the variant it lands on.
import { type CatalogVariantOption } from "@evolve-framework/payload/config";export type CatalogVariantOption = { label: string; value: string; sku: string; availability?: string;};CatalogVariantSelectorThe variant selector for a product.
import { type CatalogVariantSelector } from "@evolve-framework/payload/config";Mirrors what a product detail page renders: the dimensions are relative to the currently selected sku, so choosing an option means asking again with the sku it resolved to. A product with one variant reports no dimensions and just its sku, which is what lets the picker skip the second step entirely.
export type CatalogVariantSelector = { sku: string; dimensions: CatalogVariantDimension[];};ContentBlockDefA content block bundles everything one Payload block needs: its output typename, SDL fragment, mapper (Payload block -> GraphQL type), the Payload field config that defines it, and its composition metadata (which groups it belongs to, and which slots it exposes).
import { type ContentBlockDef } from "@evolve-framework/payload/config";A block references other blocks only by slug or group -- never by import --
so any one can be ejected while still referencing the rest. A container maps
its children by dispatching them through the registry on their blockType,
so each block owns the mapping of its own type and nothing else.
export type ContentBlockDef = { id: string; typename: string; typeDefs?: string; payload?: Block; groups?: GroupId[]; slots?: Record<string, Slot>; mapper?: ContentBlockMapper; pageMapper?: PageMapper;};ContentEventsOptionsWhere and how evolveCms publishes content-modified events.
import { type ContentEventsOptions } from "@evolve-framework/payload/config";export type ContentEventsOptions = { publisher: MessagePublisher; origin: string; locales?: Record<string, string>; retries?: number; siteRevalidation?: SiteRevalidationOptions; homePath?: string;};ContentModifiedEventThe shared content-modified message schema, as this package publishes it.
import { type ContentModifiedEvent } from "@evolve-framework/payload/config";export type ContentModifiedEvent = { type: "content-modified-event"; origin: string; timestamp: string; changes: ContentChange[];};GroupIdA slot-group: a named set of blocks that can fill a slot.
import { type GroupId } from "@evolve-framework/payload/config";export type GroupId = string;KeyPatternsA pattern per key kind; a string is read as a regular expression.
import { type KeyPatterns } from "@evolve-framework/payload/config";export type KeyPatterns = Partial<Record<KeyKind, RegExp | string>>;PageCollectionThe slugs of the page collections.
import { type PageCollection } from "@evolve-framework/payload/config";export type PageCollection = "content_page" | "catalog_page" | "article_page" | "article_overview_page";PayloadBlockThe shape every raw Payload block shares.
import { type PayloadBlock } from "@evolve-framework/payload/config";export type PayloadBlock = { blockType: string; id?: string; [key: string]: unknown;};SlotA named containment point a block exposes.
import { type Slot } from "@evolve-framework/payload/config";export type Slot = { accepts: SlotAccepts;};SlotAcceptsWhat a slot accepts.
import { type SlotAccepts } from "@evolve-framework/payload/config";export type SlotAccepts = GroupId | { group?: GroupId; ids?: string[]; exclude?: string[];};@evolve-framework/payload/graphql/context
The request context the module's resolvers expect.
Classes
StoreContextThe store, locale and currency a request is for.
import { StoreContext } from "@evolve-framework/payload/graphql/context";new StoreContext(storeContext: StoreContextInput)| Option | Type | Description |
|---|---|---|
currency | string | The currency used in the store context. |
locale | string | The locale of the store context. For example: en-US. |
storeKey | string | The store key associated with the store context. |
country? | InputMaybe<string> | The market the store context is for; leave out for every market. |
Functions
initContextValueA request's context: its store context and the data loaders built on it.
import { initContextValue } from "@evolve-framework/payload/graphql/context";function initContextValue({ request }: YogaInitialContext): ContextValueReturns ContextValue
Types
ContextValueThe GraphQL context the resolvers of this package read.
import { type ContextValue } from "@evolve-framework/payload/graphql/context";export type ContextValue = { storeContext: StoreContext; loaders: { articlesByCategoryTrail: DataLoader<string, TaggedDocument[]>; };};@evolve-framework/payload/graphql/types
The generated GraphQL types of the content contract.
Generated types237Generated from the schema, one per type.
ArticleList | Article cards: the articles the editor picked, or else the newest that match its filters on section, topic and category. |
ArticleListResolvers | |
ArticleOverviewPage | The overview of one section of articles, such as a blog or the buying guides. |
ArticleOverviewPageResolvers | |
ArticlePage | An article, such as a blog post, a buying guide or a news item: a page whose text owns it. |
ArticlePageResolvers | |
ArticleResult | One page of articles, newest first. |
ArticleResultResolvers | |
AudienceType | Who a block is shown to. |
Author | Who wrote an article, as the byline and the author markup name them. |
AuthorResolvers | |
Block | Rich text is also a block of its own, placed directly in a page body. |
BlockResolvers | |
Brand | A brand. |
BrandList | Brand logos that link to their brand pages, in the order the editor placed them. |
BrandListResolvers | |
BrandResolvers | |
Breadcrumb | Represents a single item in a breadcrumb trail. |
BreadcrumbResolvers | |
BreadcrumbType | Represents different types of breadcrumbs in the navigation structure. |
CampaignBanner | A campaign: an image with the text beside it, not on it, and one call to action. |
CampaignBannerResolvers | |
CatalogPage | Represents a product listing page with its surrounding content. |
CatalogPageFacetFilter | One facet of a curated collection and the values it selects. |
CatalogPageFacetFilterInput | One facet of a listing's filter and the values it selects. |
CatalogPageFacetFilterResolvers | |
CatalogPageLayoutType | How a catalog page presents its category. |
CatalogPageResolvers | |
CategoryList | Entrances to categories: the ones the editor picked, or the children of one category. |
CategoryListResolvers | |
ColumnEntry | Represents content types that can be used in columns. |
ColumnEntryResolvers | |
Columns | Two to four blocks side by side, stacked in their order on a narrow screen. |
ColumnsRatioType | How the width is shared between two columns, in the order they are placed. |
ColumnsResolvers | |
ContentAsset | Represents a content asset, such as an image or file. |
ContentAssetResolvers | |
ContentPage | Represents a content page with various sections and blocks. |
ContentPageResolvers | |
ContentSearchHit | A page or an article that matches a search. |
ContentSearchHitResolvers | |
ContentSearchResult | What the CMS answers to a search term. |
ContentSearchResultResolvers | |
ContentSnippet | Represents a snippet of content that can be used in various places. |
ContentSnippetResolvers | |
ContentTeaser | An image beside text, or text alone, with up to two links. |
ContentTeaserResolvers | |
ContentVersionType | Specifies different versions of content. |
CountryCodeScalarConfig | |
CurrencyScalarConfig | |
DateScalarConfig | |
DateTimeScalarConfig | |
DirectiveResolverFn | |
DirectiveResolvers | |
EmailAddressScalarConfig | |
Error | Shared interface for every error returned as data. |
ErrorResolvers | |
Faq | |
FaqGroup | |
FaqGroupResolvers | |
FaqItem | |
FaqItemResolvers | |
FaqResolvers | |
FederationReferenceTypes | Mapping of federation reference types |
FederationTypes | Mapping of federation types |
FieldValidationIssue | A single field-level validation failure, to attach to its input control |
FieldValidationIssueResolvers | |
Figure | One key figure: a value with what it measures. |
FigureList | Two to four key figures. |
FigureListResolvers | |
FigureResolvers | |
FocalPoint | A point in an image, in percent from its left and top edges. |
FocalPointResolvers | |
GraphQLRecursivePick | |
Hotspot | One product pinned on a shoppable image. |
HotspotResolvers | |
Image | One image, or a pair side by side. |
ImageResolvers | |
InputMaybe | |
IsTypeOfResolverFn | |
JsonScalarConfig | |
Link | A link with its own label, to one target: a page, a product, a storefront route or a URL. |
LinkKindType | What a resolved link points at: a page of the site, or a URL. |
LinkResolvers | |
LinkVariantType | How prominently a link is drawn. |
LocaleScalarConfig | |
Maybe | |
MenuItem | One menu entry: a link, or a heading for the entries below it. |
MenuItemResolvers | |
Messages | The store's fixed system copy, one entry per store, for the places no editor fills by hand. |
MessagesResolvers | |
Mutation | Defines the available mutations in the schema. |
MutationResolvers | |
MutationStoreContentPreviewArgs | Defines the available mutations in the schema. |
Navigation | A menu: the header's, the footer's, or one of the project's own. |
NavigationResolvers | |
NextResolverFn | |
Omit | |
OpenGraph | Open Graph protocol metadata for social media sharing |
OpenGraphResolvers | |
Page | A page a route can land on. |
PageMeta | Page metadata for SEO, from the page's three SEO fields. |
PageMetaResolvers | |
PageRedirect | Where a path sends a visitor: written by an editor, or by the CMS when a page's path changed, from the old path to the page. |
PageRedirectResolvers | |
PageResolvers | |
PageSortOrderType | Specifies sorting options for pages. |
PagesResult | Represents the result of a query for multiple pages. |
PagesResultResolvers | |
PageType | Defines the different types of pages available in the system. |
Pagination | Where a page sits within the full result set. |
PaginationResolvers | |
PaymentBrandType | A way to pay the store accepts, which the site draws as that brand's logo. |
Product | Product entity containing all product information, variants, and metadata. |
ProductCategory | Represents a category of products. |
ProductCategoryResolvers | |
ProductList | Products, either the variants the editor picked or those a source selects. |
ProductListResolvers | |
ProductResolvers | |
ProductSortOrderType | Available sorting options for product listings |
ProductSource | Which products a listing shows: those in a category, narrowed by facet selections, in a sort order. |
ProductSourceFilter | One facet of a product source and the values it selects. |
ProductSourceFilterResolvers | |
ProductSourceResolvers | |
ProductVariant | |
ProductVariantResolvers | |
Promo | A card that links somewhere. |
PromoList | Two to four promo cards side by side. |
PromoListResolvers | |
PromoResolvers | |
Query | Defines the available queries in the schema. |
QueryArticlesArgs | Defines the available queries in the schema. |
QueryCatalogPageArgs | Defines the available queries in the schema. |
QueryCatalogPageByFilterArgs | Defines the available queries in the schema. |
QueryContentPageArgs | Defines the available queries in the schema. |
QueryContentSearchArgs | Defines the available queries in the schema. |
QueryContentSnippetArgs | Defines the available queries in the schema. |
QueryMessagesArgs | Defines the available queries in the schema. |
QueryPageArgs | Defines the available queries in the schema. |
QueryPagesArgs | Defines the available queries in the schema. |
QueryRedirectArgs | Defines the available queries in the schema. |
QueryResolvers | |
QuerySiteArgs | Defines the available queries in the schema. |
QuerySiteSettingsArgs | Defines the available queries in the schema. |
ReferenceResolver | |
RequireFields | |
RequiresSessionDirectiveArgs | |
RequiresSessionDirectiveResolver | |
Resolver | |
ResolverFn | |
Resolvers | |
ResolversInterfaceTypes | Mapping of interface types |
ResolversParentTypes | Mapping between all available schema types and the resolvers parents |
ResolversTypes | Mapping between all available schema types and the resolvers types |
ResolversUnionTypes | Mapping of union types |
ResolverTypeWrapper | |
ResourceLink | Represents a link to a resource, either internal or external. |
ResourceLinkResolvers | |
ResourceLinkType | Specifies different types of resource links. |
RichText | Formatted text, the same whichever CMS wrote it. |
RichTextEmbed | What rich text can embed. |
RichTextEmbedResolvers | |
RichTextImageEmbed | An image placed in rich text. |
RichTextImageEmbedResolvers | |
RichTextLink | A link in rich text, resolved by the adapter. |
RichTextLinkResolvers | |
RichTextProductEmbed | A product placed in rich text, by its sku. |
RichTextProductEmbedResolvers | |
RichTextPromoEmbed | A promo placed in rich text. |
RichTextPromoEmbedResolvers | |
RichTextResolvers | |
RichTextShoppableImageEmbed | A shoppable image placed in rich text. |
RichTextShoppableImageEmbedResolvers | |
RichTextTipEmbed | A tip placed in rich text. |
RichTextTipEmbedResolvers | |
RichTextVideoEmbed | A video placed in rich text. |
RichTextVideoEmbedResolvers | |
Scalars | All built-in and custom scalars, mapped to their actual values |
SearchRedirect | Where a keyword rule sends a search instead of to a result page. |
SearchRedirectResolvers | |
ShareableDirectiveArgs | |
ShareableDirectiveResolver | |
ShoppableImage | One image with two to six products pinned on it, also listed beside or below it. |
ShoppableImageResolvers | |
Site | The store's settings, one per store: its menus, the selling points in the header bar, its social profiles, payment brands and review rating, and the templates the SEO title and description of a page fall back to. |
SiteResolvers | |
SiteSettings | Which page of the site answers each recurring purpose, such as the contact or the returns page, one entry per store. |
SiteSettingsResolvers | |
SocialLink | The store's profile on a social network; the site draws the network's icon. |
SocialLinkResolvers | |
SocialPlatformType | A social network a store keeps a profile on. |
Step | One step of a step list. |
StepList | Two to four numbered steps, such as how an account, a return or a job works. |
StepListResolvers | |
StepResolvers | |
StoreContentPreviewData | Represents data for storing content previews. |
StoreContentPreviewDataResolvers | |
StoreContentPreviewError | |
StoreContentPreviewErrorResolvers | |
StoreContentPreviewResponse | |
StoreContentPreviewResponseResolvers | |
StoreContext | |
StoreContextResolvers | |
StorefrontRouteType | A page the storefront itself serves rather than the CMS. |
SubscriptionObject | |
SubscriptionResolveFn | |
SubscriptionResolver | |
SubscriptionResolverObject | |
SubscriptionSubscribeFn | |
SubscriptionSubscriberObject | |
TableOfContents | Links to the anchors on the page. |
TableOfContentsResolvers | |
TimeScalarConfig | |
Tip | A highlighted tip, in a page body or inside rich text. |
TipResolvers | |
Topic | What an article is about, such as tennis or maintenance. |
TopicPage | A topic's page below a section of articles. |
TopicPageResolvers | |
TopicResolvers | |
TranslatedPath | Represents a translated path for a specific locale. |
TranslatedPathResolvers | |
TrustRating | The store's average review score at a review service, such as 9.2 out of 10 from 1,284 reviews, as an editor entered it. |
TrustRatingResolvers | |
TypeResolveFn | |
UrlScalarConfig | |
Usp | Represents a single Unique Selling Point (USP). |
UspIconType | The icon a selling point shows, from a fixed set the storefront maps to its own glyphs. |
UspList | The store's selling points, two to six of them. |
UspListResolvers | |
UspResolvers | |
ValidationError | The input was malformed: one or more fields need editing before the operation can succeed. |
ValidationErrorResolvers | |
Video | A YouTube video, played from the privacy-enhanced domain once the visitor consents. |
VideoResolvers | |
WithInternalFields | A GraphQL type T that can also carry its source object (__instance) and its own field resolvers (__fieldResolvers). |
YoutubeVideo | A YouTube video embedded in rich text. |
YoutubeVideoResolvers |
@evolve-framework/payload/testing
A test configuration, tenant seeding and a test executor.
Functions
createTestConfigA real Payload config, assembled exactly the way a project assembles one, on an in-memory sqlite database.
import { createTestConfig } from "@evolve-framework/payload/testing";The other CMS packages mock the vendor's HTTP API with MSW; here the package owns the config, so a test can run the actual Payload against actual storage. That catches block and collection drift the fixtures never would.
function createTestConfig( blocks?: ContentBlockDef[],): Promise<import("payload").SanitizedConfig>Returns Promise<import("payload").SanitizedConfig>
createTestExecutorA GraphQL executor for tests.
import { createTestExecutor } from "@evolve-framework/payload/testing";function createTestExecutor(): DisposableAsyncExecutorReturns DisposableAsyncExecutor
seedTenantSeed the tenant the test store context resolves to.
import { seedTenant } from "@evolve-framework/payload/testing";The test executor sends X-StoreContext-StoreKey: example, and every resolver
matches documents on tenant.slug === storeKey — so without this, reads find
nothing.
function seedTenant(slug?: string | undefined): Promise<JsonObject & TypeWithID>Returns Promise<import("payload").JsonObject & import("payload").TypeWithID>
@evolve-framework/payload/admin
The admin UI components for picking products, variants and categories from the catalog.
Functions
BlockRowLabelThe collapsed label of a block row: its number, its type and the first of titleFields that holds text, else "Untitled".
import { BlockRowLabel } from "@evolve-framework/payload/admin";| Prop | Type | Description |
|---|---|---|
blockLabel | string | |
titleFields | string[] |
CategoryPickerPick a category, and store the engine's id for it.
import { CategoryPicker } from "@evolve-framework/payload/admin";Catalog pages normally get this from the category events, which create the page and fill the id in. This is for the page an editor makes by hand — the one case where the join key would otherwise be copied out of a commerce admin.
Each result carries its ancestor trail and its path, because category names repeat: "Shirts" under Men and under Women are different pages, and the name alone cannot tell an editor which one they are about to point at.
| Prop | Type | Description |
|---|---|---|
value | string | undefined | |
setValue | (value: string) => void | |
apiBase | string | Where Payload's REST API is mounted, e.g. MorePassed in rather than derived from the url. The admin and the api are
mounted independently — this project serves |
CategoryPickerFieldThe category picker as a Payload text field.
import { CategoryPickerField } from "@evolve-framework/payload/admin";| Prop | Type | Description |
|---|---|---|
field | Omit<TextFieldClient, "type"> & Partial<Pick<TextFieldClient, "type">> | |
path | string | |
readOnly? | boolean | |
forceRender? | boolean | Controls the rendering behavior of the fields, i.e. defers rendering until they intersect with the viewport using the Intersection Observer API. MoreIf true, the fields will be rendered immediately, rather than waiting for them to intersect with the viewport. If a number is provided, will immediately render fields up to that index. |
permissions? | SanitizedFieldPermissions | |
renderedBlocks? | RenderedField[] | |
schemaPath? | stringDefault: field.name | Used to extract field configs from a schemaMap. Does not include indexes. |
inputRef? | RefObject<HTMLInputElement> | |
onKeyDown? | KeyboardEventHandler<HTMLInputElement> | |
validate? | TextFieldValidation |
ProductPickerPick a product, and store its slug.
import { ProductPicker } from "@evolve-framework/payload/admin";A product link points at a product, not a variant, so this stops where the variant picker continues. The slug is the canonical one the engine reports; the storefront resolves the reader's locale from it, the same way a catalog page does.
| Prop | Type | Description |
|---|---|---|
value | string | undefined | |
setValue | (value: string) => void | |
apiBase | string | Where Payload's REST API is mounted, e.g. MorePassed in rather than derived from the url. The admin and the api are
mounted independently — this project serves |
ProductPickerFieldThe product picker as a Payload text field.
import { ProductPickerField } from "@evolve-framework/payload/admin";| Prop | Type | Description |
|---|---|---|
field | Omit<TextFieldClient, "type"> & Partial<Pick<TextFieldClient, "type">> | |
path | string | |
readOnly? | boolean | |
forceRender? | boolean | Controls the rendering behavior of the fields, i.e. defers rendering until they intersect with the viewport using the Intersection Observer API. MoreIf true, the fields will be rendered immediately, rather than waiting for them to intersect with the viewport. If a number is provided, will immediately render fields up to that index. |
permissions? | SanitizedFieldPermissions | |
renderedBlocks? | RenderedField[] | |
schemaPath? | stringDefault: field.name | Used to extract field configs from a schemaMap. Does not include indexes. |
inputRef? | RefObject<HTMLInputElement> | |
onKeyDown? | KeyboardEventHandler<HTMLInputElement> | |
validate? | TextFieldValidation |
VariantPickerPick a product variant, and store its sku.
import { VariantPicker } from "@evolve-framework/payload/admin";Two steps, because a sku identifies a variant and a product that comes in
sizes and colours has several. Searching lands on the product; the dimensions
then resolve which one, the way a product detail page does — so an editor
chooses "M" and "Black" rather than recalling T-SHIRT-M-BLACK.
The stored value is still the sku, so nothing downstream changes: this replaces how the field is filled in, not what it holds. A project without a catalogue wired up keeps a plain text input.
| Prop | Type | Description |
|---|---|---|
value | string | undefined | |
setValue | (value: string) => void | |
apiBase | string | Where Payload's REST API is mounted, e.g. MorePassed in rather than derived from the url. The admin and the api are
mounted independently — this project serves |
VariantPickerFieldThe variant picker as a Payload text field.
import { VariantPickerField } from "@evolve-framework/payload/admin";| Prop | Type | Description |
|---|---|---|
field | Omit<TextFieldClient, "type"> & Partial<Pick<TextFieldClient, "type">> | |
path | string | |
readOnly? | boolean | |
forceRender? | boolean | Controls the rendering behavior of the fields, i.e. defers rendering until they intersect with the viewport using the Intersection Observer API. MoreIf true, the fields will be rendered immediately, rather than waiting for them to intersect with the viewport. If a number is provided, will immediately render fields up to that index. |
permissions? | SanitizedFieldPermissions | |
renderedBlocks? | RenderedField[] | |
schemaPath? | stringDefault: field.name | Used to extract field configs from a schemaMap. Does not include indexes. |
inputRef? | RefObject<HTMLInputElement> | |
onKeyDown? | KeyboardEventHandler<HTMLInputElement> | |
validate? | TextFieldValidation |
VariantRowLabelThe collapsed label of a product row.
import { VariantRowLabel } from "@evolve-framework/payload/admin";Payload labels a block row by a field it recognises, and a variant row holds only a sku — so every row reads "Untitled" and a list of six products cannot be told apart while collapsed. The product name comes from the same lookup the picker uses, with the sku beside it because the whole point of the row is which variant.
Falls back to the sku alone while the lookup is in flight, so the row never flashes empty.
| Prop | Type | Description |
|---|---|---|
sku | string | undefined | |
apiBase | string |
VariantRowLabelFieldThe collapsed label of a product variant row.
import { VariantRowLabelField } from "@evolve-framework/payload/admin";Types
PickerPropsWhat a picker needs, and nothing more.
import { type PickerProps } from "@evolve-framework/payload/admin";Deliberately not Payload's TextFieldClientProps, and deliberately no
useField. These components are consumed as source and transpiled by the
project that uses them, so an import of @payloadcms/ui here resolves
against this package rather than the admin app — and pnpm will happily
produce a second copy whose hooks are undefined inside the first copy's
render tree.
So the field binding stays in the admin app, which has exactly one copy, and the app's own wrapper hands the value down.
export type PickerProps = { value: string | undefined; setValue: (value: string) => void; apiBase: string;};@evolve-framework/payload/migrations/drop-removed-schema
A predefined migration, for payload migrate:create --file, that drops the tables, enums and columns the config no longer declares.
Functions
dynamicThe migration template: up drops what the config removed, down recreates it, and the pruned snapshot is written for the next migration to diff against.
import { dynamic } from "@evolve-framework/payload/migrations/drop-removed-schema";function dynamic( args: { filePath: string; payload: BasePayload; },): Promise<{ downSQL?: string; imports?: string; upSQL?: string;}>Returns Promise<{ downSQL?: string; imports?: string; upSQL?: string; }>
withoutRemovedbefore without anything after lacks.
import { withoutRemoved } from "@evolve-framework/payload/migrations/drop-removed-schema";function withoutRemoved(before: Snapshot, after: Snapshot): Snapshot| Option | Type | Description |
|---|---|---|
id | string | |
prevId | string | |
version | string | |
tables | Record<string, Record<string, unknown>> | |
id | string | |
prevId | string | |
version | string | |
tables | Record<string, Record<string, unknown>> | |
enums? | Record<string, unknown> | |
enums? | Record<string, unknown> |
Returns Snapshot
Not listed: 8 options types. They appear as the tables under the constructors and functions they type.

