Example
Parameters
DetailPageOptions<T, C, U, EntityField, VarNameCreate, VarNameUpdate>Options used to configure the result of the useDetailPage hook.
stringThe page id. This is optional, but if provided, it will be used to identify the page when extending the detail page query
TThe query document to fetch the entity.
EntityFieldThe field of the query document that contains the entity.
{ id: string; }The parameters used to identify the entity.
stringThe entity type name for custom field configuration lookup. Required to filter out readonly custom fields before mutations. If not provided, the function will try to infer it from the query document.
CThe document to create the entity.
UThe document to update the entity.
( entity: NonNullable<ResultOf<T>[EntityField]>, ) => WithLooseCustomFields<VariablesOf<U>[VarNameUpdate]>The function to set the values for the update document.
NoInfer< (params: Record<string, string>) => WithLooseCustomFields<Partial<VariablesOf<C>[VarNameCreate]>> >v3.8.0The function to set the starting values for the create form, e.g. a parent ID from the
route params. It receives the path params of the matched route, not the params option.
It runs again only when the route params change. The starting values count as
unsaved changes, so a submit button disabled on !form.formState.isDirty is enabled, and leaving
the page asks the user to confirm.
Example
(input: VariablesOf<C>[VarNameCreate]) => VariablesOf<C>[VarNameCreate](variables: VariablesOf<C>) => VariablesOf<C>v3.8.0Adjusts the full set of variables sent to the create mutation, for a create mutation which
takes more than the input object, such as createCustomer(input:, password:). Runs after
transformCreateInput, which has already shaped variables.input.
(input: VariablesOf<U>[VarNameUpdate]) => VariablesOf<U>[VarNameUpdate](schema: ZodObject<any>) => ZodTypeAnyv3.7.0Refines the auto-generated Zod schema for this page's form. Use this to declare the fields the user must actually fill in.
The generated schema is derived from the GraphQL input type, which only expresses nullability — and nullability tells you nothing about whether a value is required:
String! means "not null",
not "not empty", and a non-nullable ID! such as CreateFacetValueInput.facetId
may be supplied by the page in transformCreateInput rather than by the user.CreateChannelInput. defaultCurrencyCode is nullable, yet ChannelService.create rejects the input
unless it is set.So required-ness is declared per page, here.
Example
booleanv3.8.0falseBy default an update mutation sends the full form payload. Set this to true to instead send
only the fields the user actually changed, so that an untouched field's stale page-load value
cannot silently overwrite a concurrent change made by another admin or via the API.
Only enable this for a detail page whose update mutation is patch-style: an absent field must
be left unchanged, and no persisted value may be derived from the (now partial) input.
Vendure's built-in Product, Collection and ProductVariant update paths satisfy this; a
resolver that recomputes a field from the input — as updatePromotion does for
priorityScore — does not, and would corrupt that field when it is omitted.
(entity: ResultOf<C>[keyof ResultOf<C>] | ResultOf<U>[keyof ResultOf<U>]) => voidThe function to call when the update is successful.
(error: unknown) => voidThe function to call when the update is successful.
Architecture reviews, custom plugin work, migrations, ongoing support. Get a hand from the team that builds Vendure.
Talk to the team