Custom Schema Fields
Custom schema fields let you teach SchemaForm a new $field type.
Field anatomy
Most custom schema fields follow the same shape:
- Read the current value from the form engine.
- Update the value when the input changes.
- Render the field UI such as label, instructions, and errors.
- Register the field under a
$fieldname.
The package's FieldLayout helper is useful here because it gives your custom field the same label, instruction, and error presentation as the built-in fields.
React field example
import { Input } from '@verbb/plugin-kit-react/components';
import { FieldLayout, useEngineField } from '@verbb/plugin-kit-react/forms';
import type { SchemaFormFieldComponent } from '@verbb/plugin-kit-react/forms/engine/context';
const ApiTokenField: SchemaFormFieldComponent = ({ form, field }) => {
const { value, setValue, errors } = useEngineField(form, field.name);
return (
<FieldLayout
name={field.name}
label={field.label}
instructions={field.instructions}
errors={errors}
required={field.required}
>
<Input
value={String(value ?? '')}
onChange={(event) => {
setValue(event.currentTarget.value);
}}
/>
</FieldLayout>
);
};This example shows the core pattern:
useEngineField()connects the field to the SchemaForm storeFieldLayoutrenders the shared field UI- your input writes back through
setValue()
Register it during bootstrap
import { registerFormFields } from '@verbb/plugin-kit-react/forms';
registerFormFields({
apiToken: ApiTokenField,
});Like custom schema components, this should happen before your React app renders the SchemaForm screen.
Reference it from PHP schema
$schema[] = [
'$field' => 'apiToken',
'name' => 'apiToken',
'label' => Craft::t('my-plugin', 'API token'),
'instructions' => Craft::t('my-plugin', 'Paste the token from your external service.'),
];That is the full loop:
- PHP outputs
$field => 'apiToken' - React registers
apiToken - SchemaForm renders your custom field when it sees that schema node
When to use FieldLayout
You do not have to use FieldLayout, but it is usually the right default when you want your custom field to feel consistent with the rest of SchemaForm.
It handles:
- labels
- instructions
- inline errors
- required state
If your field needs a more unusual structure, you can build your own field layout with the lower-level field helpers, but most consumers should start with FieldLayout.
Related
- Read Schema Fields for the broader field model.
- Read SchemaForm Registry for the registration APIs.
- Browse the built-in schema field pages in this section for implementation patterns you can copy.