All articles
Form Builder
Schema
JSON forms

Form Builder schema explained

A practical reference for FormBuilderSchema: what each top-level property does, how sections and fields are ordered, where validation lives, and how custom settings are stored for renderers.

June 18, 20269 min read

The schema shape

FormBuilderSchema is the JSON contract between the visual builder, your backend, and ngs-form-renderer. The required property is sections; top-level fields and layout are optional, but useful when a form mixes standalone fields and sections.

form-builder-schema.ts
const schema: FormBuilderSchema = {
  title: 'Customer intake',
  fields: [
    {
      id: 'source',
      name: 'source',
      type: 'select',
      label: 'Source',
      width: 6,
      options: [
        { label: 'Website', value: 'website' },
        { label: 'Referral', value: 'referral' },
      ],
    },
  ],
  sections: [
    {
      id: 'contact',
      title: 'Contact',
      description: 'Basic customer contact details.',
      fields: [
        {
          id: 'email',
          name: 'email',
          type: 'email',
          label: 'Email',
          placeholder: 'name@example.com',
          required: true,
          width: 6,
        },
      ],
    },
  ],
  layout: [
    { kind: 'field', id: 'source' },
    { kind: 'section', id: 'contact' },
  ],
};

Top-level properties

  • title is optional metadata for your app, storage, or surrounding page UI.
  • fields stores top-level fields that are not inside a section.
  • sections stores named groups of fields and is always present.
  • layout stores the visual order of top-level fields and sections.

If layout is missing, the renderer appends top-level fields first and then sections. If layout contains stale ids, they are ignored.

Sections

A section has an id, title, optional description, optional collapsed state, and a fields array. Use sections for visible form groups such as Contact, Billing, Security, or Approval details.

Fields

A field's id is for builder layout and selection. Its name is the Angular form control key and the value key emitted by the renderer. The type must match a registered field definition, either one of the built-in fields or a custom field registered with provideFormBuilderField.

field.ts
Loading…

Layout ordering

The layout array controls only top-level ordering. Section field order is stored inside each section's fields array, and nested container order is stored inside children.

layout.ts
Loading…

Options and defaults

Choice fields use options. The renderer uses defaultValue when it exists; otherwise selected options become the initial value for select, radio, and multiple-choice fields.

options.ts
Loading…

Validation

required adds required validation. The validation array adds declarative rules such as email, minLength, maxLength, min, and max. A custom field definition can override this with its own validators factory.

Settings

settings is the extensibility bag. Built-in fields use it for values such as upload accept types, repeater empty text, radio orientation, and static spacer height. Custom fields should store renderer-specific configuration there too.

Nested fields

Layout fields such as group and repeater use children. Groups flatten child controls into the current form group. Repeaters create a FormArray of row groups from their child fields.

nested-fields.ts
Loading…

Storage checklist

  • Persist the whole FormBuilderSchema as JSON.
  • Keep field id values stable so layout references remain valid.
  • Keep field name values stable when submitted data already exists.
  • Store custom renderer options under settings.
  • Version schemas in your backend when production forms change over time.