Getting started
To render a dynamic form, you need:- A schema — the JSON Schema defining data types and validation
- A uiSchema — the UI Schema defining layout and controls
- A data — (optional) existing data to prefill the form
- A renderer — either a JSON Forms library or your own implementation
Using JSON Forms libraries
The fastest way to get started is using an official JSON Forms renderer: These libraries handle schema interpretation, validation, and rendering out of the box.Schema-level hints
The JSON Schema includes aformat keyword that indicates how a field should be rendered. Use it to select the appropriate input component:
| Format | Implementation |
|---|---|
format: "date" | Render a date picker input |
Custom renderers for Enterprise API Suite
The UI Schema extends JSON Forms with customoptions that require additional rendering logic:
| Option | Implementation |
|---|---|
data.source | Populate options from any data source (API, database, etc.) based on the source identifier. The Enterprise API Suite provides endpoints for available sources. |
data.exclude | Filter the data source based on the specified restriction |
format: "postal-code" | Render a postal code input with country-aware formatting |
rules | Apply client-side validation rules (e.g., age thresholds) |
dependsOn | Re-fetch or update the control when a dependency value changes |
Building a custom renderer
If you need full control over the user experience, you can build your own form renderer. Your implementation must:- Parse the schema — Extract property definitions, types, and validation rules
- Parse the uiSchema — Build the layout tree from elements
- Render controls — Map schema types to appropriate input components
- Apply rules — Evaluate conditions and show/hide/enable/disable elements
- Validate input — Enforce schema constraints before submission
- Handle progressive disclosure — Re-render when the API returns updated schemas
Handling progressive disclosure
When implementing progressive disclosure:- Render the form from
schema,uiSchema, and any existingdata - Collect user input for the current step (Category)
- Submit the answers to the API
- Compare the new response with the previous one:
- If there’s a new root property in the schema, or a new Category in the uiSchema, re-render the form to show the new questions
- If the schema and uiSchema are unchanged, the form is complete
Examples: React custom renderers
The examples below show how to implement custom renderers using JSON Forms for React and Material UI. Each renderer follows the same pattern: a tester that matches specific UI Schema options, and a control component that renders the appropriate input.Country renderer (data.source: "countries")
Fetches the country list and applies data.exclude filters.
In this example, the data is fetched from List countries endpoint.
- Detecting the
data.sourceoption with a custom tester - Fetching options from the API and applying
data.excludefilters - Using Material UI’s Autocomplete for consistent styling
- Passing existing
datato prefill the form
Subdivision renderer (data.source: "subdivisions" + dependsOn)
Fetches subdivisions based on the selected country. Uses dependsOn to read the current country value and re-fetch when it changes.
In this example, the data is fetched from Get country endpoint.
- Reading dependency values from
dependsOnusingResolve.dataandtoDataPath - Re-fetching subdivisions from Get country when the country changes
- Clearing the selected value when the dependency changes (except on initial render)
- Disabling the control until a country is selected
Date renderer (format: "date" + rules)
Renders a date picker and converts rules (e.g., difference-greater-than-or-equal-to-threshold, difference-less-than-or-equal-to-threshold) into min/max date constraints. The format: "date" is defined in the JSON Schema; this renderer adds support for the rules option from the UI Schema.
- Detecting
format: "date"in the JSON Schema with a custom tester - Delegating rule evaluation to a partner-implemented function
- Applying
min/maxconstraints to the native date input
Postal code renderer (format: "postal-code" + dependsOn)
Renders a text input for postal codes. Uses dependsOn to read the current country and subdivision values, then applies country-specific validation patterns.
- Reading multiple dependency values (
country,subdivision) fromdependsOn - Delegating pattern resolution to a partner-implemented service
- Applying regex validation against the resolved pattern
- Disabling the control until a country is selected
Registering all custom renderers
Register all custom renderers with theJsonForms component:
See it in action
To see dynamic forms in practice, explore the KYC processes that use them:KYC Processes
Learn how dynamic forms power KYC data collection.