FormBuilder
FormBuilder is the editing component. It displays the catalog, canvas, selected field properties, preview mode and import/export actions.
Basic usage
<script setup lang="ts">
import type { FormKitSchemaDefinition } from '@formkit/core'
const schema = ref<FormKitSchemaDefinition[]>([])
const values = ref<Record<string, unknown>>({})
</script>
<template>
<ClientOnly>
<FormBuilder
builder-id="contact"
v-model:schema="schema"
v-model:values="values"
/>
</ClientOnly>
</template>ClientOnly is recommended in Nuxt to avoid rendering the visual editor during SSR.
Save
<script setup lang="ts">
import type { FormKitSchemaDefinition } from '@formkit/core'
type SavePayload = {
builderId: string
schema: FormKitSchemaDefinition[]
values: Record<string, unknown>
settings: Record<string, unknown>
}
const schema = ref<FormKitSchemaDefinition[]>([])
const values = ref<Record<string, unknown>>({})
async function saveForm(payload: SavePayload) {
await $fetch('/api/forms/contact', {
method: 'PUT',
body: payload,
})
}
</script>
<template>
<ClientOnly>
<FormBuilder
builder-id="contact"
v-model:schema="schema"
v-model:values="values"
autosave
@save="saveForm"
/>
</ClientOnly>
</template>The @save payload contains the data required to render the form with FormViewer.
Responsive drawers
The builder computes drawers from its rendered width. It can be placed in a full page, card, tab or resizable panel.
| Mode | Behavior |
|---|---|
default | Auto-fit. Drawers become overlays when space is limited. |
desktop | Drawers remain persistent. |
mobile | One overlay drawer at a time. |
<FormBuilder
builder-id="embedded-contact"
drawer-behavior="default"
height="720px"
/>Selection and drag-and-drop
The canvas uses one interaction session for click, selection, drag-and-drop and drop. This avoids synthetic post-drag clicks and keeps selection coherent across catalog, canvas and tree.
data-qform-interaction-phase, data-qform-selected-field and data-qform-drag-source are diagnostic and test attributes.
Reference API
<script setup lang="ts">
import type { FormKitSchemaDefinition } from '@formkit/core'
type FormBuilderPublicApi = {
save: () => {
builderId: string
schema: FormKitSchemaDefinition[]
values: Record<string, unknown>
settings: Record<string, unknown>
}
reset: () => void
exportSchema: () => FormKitSchemaDefinition[]
importSchema: (schema: FormKitSchemaDefinition[]) => void
}
const builderRef = ref<FormBuilderPublicApi | null>(null)
function downloadSchema() {
const schema = builderRef.value?.exportSchema() ?? []
const blob = new Blob([JSON.stringify(schema, null, 2)], { type: 'application/json' })
const url = URL.createObjectURL(blob)
const anchor = document.createElement('a')
anchor.href = url
anchor.download = 'contact.schema.json'
anchor.click()
URL.revokeObjectURL(url)
}
</script>
<template>
<QBtn label="Export" color="primary" @click="downloadSchema" />
<FormBuilder ref="builderRef" builder-id="contact" />
</template>Common options
| Option | Description |
|---|---|
builder-id | Stable identifier; required in practice. |
v-model:schema | FormKit/Quasar schema produced by the builder. |
v-model:values | Preview values or initial values. |
v-model:preview-mode | editing or previewing. |
autosave | Enables local safety save. |
storage-key | Explicit autosave key. |
locale | fr or en. |
catalog | Custom catalog. |
config-panels | Custom settings panels. |
See Props, events and API for the full contract.