Skip to content
Playground Form Builder

Merger Setup

Starting with version 3, you must provide a createMerger option when creating forms to enable FormMerger instantiation. This merger handles the combination and processing of JSON schemas within your forms.

The following configuration will work for most projects:

import { createFormMerger } from "@sjsf/form/mergers/modern";
const form = createForm({
createMerger: createFormMerger,
// ... other form options
});

For projects with specific requirements, you may need to customize the createFormMerger options to achieve the desired behavior.

Sometimes you need to override properties of a referenced schema. For example, when you have a schema like this:

{
"title": "bar",
"$ref": "#/definitions/foo"
}

Option 1: Override the mergeSchemas method

import { createFormMerger } from "@sjsf/form/mergers/modern";
import { mergeSchemas } from "@sjsf/form/mergers/legacy";
const createMerger = (options: MergerFactoryOptions) => {
return {
...createFormMerger(options),
mergeSchemas,
}
}

Option 2: Provide a custom merger for specific properties

import { createMerger as createJsonSchemaMerger } from "@sjsf/lib/json-schema";
import { createFormMerger } from "@sjsf/form/mergers/modern";
export const createMerger = (options: MergerFactoryOptions) => createFormMerger({
...options,
jsonSchemaMerger: createJsonSchemaMerger({
mergers: {
title: (_, r) => r, // Always use the rightmost non-undefined value
}
})
})

The modern merger (recommended since v3) can be extended to handle specific scenarios involving the allOf keyword.

Deduplication for Complex Schemas

When merging schemas containing oneOf, anyOf, or not within allOf keywords, you may encounter duplicates in the merged result. The same issue can occur with enum keywords containing non-primitive values.

To resolve this, configure JSON schema deduplication and intersection functions:

import { createDeduplicator, createIntersector } from "@sjsf/form/lib/array";
import { createComparator, createMerger as createJsonSchemaMerger } from "@sjsf/lib/json-schema";
import { createFormMerger } from "@sjsf/form/mergers/modern";
const { compareSchemaValues, compareSchemaDefinitions } = createComparator();
export const createMerger = (options: MergerFactoryOptions) => createFormMerger({
...options,
jsonSchemaMerger: createJsonSchemaMerger({
intersectJson: createIntersector(compareSchemaValues),
deduplicateJsonSchemaDef: createDeduplicator(compareSchemaDefinitions),
})
})

What this configuration does:

  • intersectJson: Handles intersection of JSON values
  • deduplicateJsonSchemaDef: Removes duplicate schema definitions

To customize how default values are handled in your forms, you can configure the default form state behavior:

If you need to preserve v2 behavior during migration or have compatibility requirements, you can use the legacy merger. However, this approach is not recommended for new projects.

The legacy merger requires additional dependencies:

Terminal window
npm i json-schema-merge-allof @types/json-schema-merge-allof
import { createFormMerger } from "@sjsf/form/mergers/legacy";
const form = createForm({
createMerger: createFormMerger,
// ... other form options
});