Pular para o conteúdo principal

FAQ & Troubleshooting

Installation & setup

I installed the package but TypeScript does not recognize the types

Make sure your tsconfig.json has moduleResolution: "bundler" or "node16":

{
"compilerOptions": {
"moduleResolution": "bundler"
}
}

If you use Vite, add to vite.config.ts:

import { defineConfig } from "vite";
export default defineConfig({
optimizeDeps: {
include: ["@schema-forms-data/renderer"],
},
});

I get "Cannot find module 'lucide-react'"

lucide-react is a peer dependency and must be installed separately:

npm install lucide-react

I get "Module not found: @dnd-kit/core" when using the builder

The dnd-kit packages are peer dependencies of the builder:

npm install @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities

FormRenderer

The form doesn't advance to the next step

Make sure all obrigatorio: true fields in the current step are filled. Fields with async validate[] validators can also block navigation.

To see exactly which fields have errors, use useFormState():

const { errors } = useFormState();
console.log(errors); // { field_name: 'error message' }

onComplete is never called

onComplete is only called on the last step. If the schema has multiple steps, the previous ones call onSubmitStep. Make sure the last step can be submitted without errors.


Fields with tipo: 'cep' don't auto-fill other fields

Check that:

  1. The field has cepFillMap configured with the correct mappings
  2. The nome of the target fields match the keys in cepFillMap
  3. cepLookup is returning the correct format ({ logradouro, bairro, cidade, estado })
{
"nome": "cep",
"tipo": "cep",
"cepFillMap": {
"logradouro": "endereco",
"bairro": "bairro",
"cidade": "cidade",
"estado": "uf"
}
}

File upload doesn't work

The file field requires uploadFile to be passed as a prop to FormRenderer. Without it, the field appears but no upload happens:

<FormRenderer
schema={schema}
uploadFile={async (file, fieldName) => {
// must return a string (URL or ID)
return await myApi.upload(file);
}}
onComplete={handler}
/>

Conditionals don't work as expected

Check the operator and value:

  • For checkboxes: "valor": true (boolean, not the string "true")
  • For selects: compare with the option's valor, not its label
  • vazio / naoVazio don't need a valor
// ✅ Correct
{ "campo": "consent", "operador": "igual", "valor": true }

// ❌ Wrong
{ "campo": "consent", "operador": "igual", "valor": "true" }

initialValues doesn't pre-fill fields

Make sure the keys in initialValues match the nome (not the id) of each field:

// ✅ Correct: key = FormField.nome
initialValues={{ name: "John", email: "john@email.com" }}

// ❌ Wrong: key = FormField.id
initialValues={{ "f-name": "John", "f-email": "john@email.com" }}

How do I reset the form from outside <FormRenderer>?

It's only possible from within the <FormRenderer> tree via useFormApi(). A common workaround is to force a remount with key:

function ResettableForm() {
const [key, setKey] = useState(0);

return (
<div>
<FormRenderer key={key} schema={schema} onComplete={handler} />
<button onClick={() => setKey((k) => k + 1)}>Reset</button>
</div>
);
}

Builder

The canvas is empty when passing schema={null}

This is expected — null means "start a brand new form". The builder automatically initializes with one empty step and container.


builderToFormSchema returns empty steps

Make sure fields were added inside containers, which in turn are inside steps. The structure must be root → step → container → field.


How do I auto-save the schema on every change?

Use onValuesChange with builderToFormSchema inside a child component with useBuilder:

function AutoSave() {
const { containers, configs, stepConfig } = useBuilder();

useEffect(() => {
const schema = builderToFormSchema({ containers }, configs, {
nome: "My Form",
status: "ativo",
stepConfig,
});
myApi.autoSave(schema);
}, [containers, configs, stepConfig]);

return null;
}

Drag-and-drop doesn't work

Make sure BuilderDndContext wraps the builder components:

<BuilderWrapper schema={null}>
<BuilderDndContext>
{" "}
{/* ← obrigatório */}
<Palette />
<Canvas />
</BuilderDndContext>
</BuilderWrapper>

Templates

My custom template doesn't appear in the builder

The template must be registered before rendering the builder or renderer:

// main.tsx or App.tsx — before any render
import { registerTemplate } from "@schema-forms-data/templates";

registerTemplate({
id: "my-brand",
displayName: "My Brand",
colors: { ... },
layout: { ... },
});

The template's CSS variables are not being applied

Make sure the package CSS is imported. Add to your application entry point:

import "@schema-forms-data/ui/style.css";

General questions

Can I use FormRenderer without the builder?

Yes. The renderer is completely independent. You can write schemas manually or generate them in code and render them directly.

Does SchemaForms Data work with Next.js?

Yes, but since the renderer uses React hooks that depend on the DOM, add "use client" to components that use FormRenderer or BuilderWrapper.

Can I use SchemaForms Data with strict TypeScript (strict: true)?

Yes. All packages export complete types and are fully compatible with strict TypeScript.

Where is the form state stored between steps?

FormRenderer accumulates values across steps as the user advances. onComplete receives the merged values from all steps. You can also persist via onSubmitStep and restore with initialValues.

What is the difference between validate[] and warn[]?

Both run the same validator functions. The difference is that validate[] blocks navigation/submit when a message is returned, while warn[] displays the message but allows the user to continue.