***

title: "UseGeneratedForm"
generated: true
---------------

## useGeneratedForm

<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/form-engine/use-generated-form.tsx" sourceLine="130" packageName="@vendure/dashboard" since="3.3.0" />

This hook is used to create a form from a document and an entity.
It will create a form with the fields defined in the document's input type.
It will also create a submit handler that will submit the form to the server.

This hook is mostly used internally by the higher-level [useDetailPage](/current/core/reference/dashboard/detail-views/use-detail-page#usedetailpage) hook,
but can in some cases be useful to use directly.

*Example*

```tsx
const { form, submitHandler } = useGeneratedForm({
 document: setDraftOrderCustomFieldsDocument,
 varName: undefined,
 entity: entity,
 setValues: entity => {
   return {
     orderId: entity.id,
     input: {
       customFields: entity.customFields,
     },
   };
 },
});
```

```ts title="Signature"
function useGeneratedForm<T extends TypedDocumentNode<any, any>, VarName extends keyof VariablesOf<T> | undefined, E extends Record<string, any> = Record<string, any>>(options: GeneratedFormOptions<T, VarName, E>): void
```

Parameters

### options

\<MemberInfo kind="parameter" type={`<a href='/current/core/reference/dashboard/detail-views/use-generated-form#generatedformoptions'>GeneratedFormOptions</a><T, VarName, E>`} />

## GeneratedFormOptions

<GenerationInfo sourceFile="packages/dashboard/src/lib/framework/form-engine/use-generated-form.tsx" sourceLine="39" packageName="@vendure/dashboard" since="3.3.0" />

Options for the useGeneratedForm hook.

```ts title="Signature"
interface GeneratedFormOptions<T extends TypedDocumentNode<any, any>, VarName extends keyof VariablesOf<T> | undefined = 'input', E extends Record<string, any> = Record<string, any>> {
    document?: T;
    varName?: VarName;
    entity: E | null | undefined;
    customFieldConfig?: any[];
    extendSchema?: (schema: ZodObject<any>) => ZodTypeAny;
    setValues: (
        entity: NonNullable<E>,
    ) => WithLooseCustomFields<
        VarName extends keyof VariablesOf<T> ? VariablesOf<T>[VarName] : VariablesOf<T>
    >;
    onSubmit?: (
        values: VarName extends keyof VariablesOf<T> ? VariablesOf<T>[VarName] : VariablesOf<T>,
    ) => void;
}
```

<div className="members-wrapper">

### document

\<MemberInfo kind="property" type={`T`}   />

The document to use to generate the form.

### varName

\<MemberInfo kind="property" type={`VarName`}   />

The name of the variable to use in the document.

### entity

\<MemberInfo kind="property" type={`E | null | undefined`}   />

The entity to use to generate the form.

### customFieldConfig

\<MemberInfo kind="property" type={`any[]`}   />

### extendSchema

\<MemberInfo kind="property" type={`(schema: ZodObject<any>) => ZodTypeAny`}  since="3.7.0"  />

Refines the auto-generated Zod schema before it is passed to the form resolver. Use this
to declare the fields which must actually be filled in by the user.

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:

* A non-nullable field may still be legitimately empty. `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.
* A nullable field may still be required by the server. `CreateChannelInput.
  defaultCurrencyCode` is nullable, yet `ChannelService.create` rejects the input unless
  it is set.

Note that this is read once, when the schema is first built: it is held in a ref so that
an inline arrow function does not replace the resolver on every render.

*Example*

```ts
extendSchema: schema =>
    schema.extend({
        code: z.string().min(1, { message: t`This field is required` }),
    }),
```

### setValues

\<MemberInfo kind="property" type={`(         entity: NonNullable<E>,     ) => WithLooseCustomFields<         VarName extends keyof VariablesOf<T> ? VariablesOf<T>[VarName] : VariablesOf<T>     >`}   />

### onSubmit

\<MemberInfo kind="property" type={`(         values: VarName extends keyof VariablesOf<T> ? VariablesOf<T>[VarName] : VariablesOf<T>,     ) => void`}   />

</div>
