FormForgeRenderer
FormForgeRenderer renders and can submit a FormForge form.
The component resolves two explicit external paths internally:
- external model mode (
modelValueprovided) - external schema mode (
schemaprovided)
Internal mode
Pass only a form key and let the component manage load and submit.
<FormForgeRenderer :form-key="'contact'" />
Standalone hybrid mode (form-key + v-model)
You can combine form-key with v-model (modelValue) to read form data in real time without final internal submission.
<script setup lang="ts">
const formData = ref<Record<string, unknown>>({})
</script>
<template>
<FormForgeRenderer
form-key="my-form"
v-model="formData"
/>
</template>
When modelValue is provided:
- the renderer emits
update:modelValueon every field change - form submit does not trigger backend submission from the renderer
- submit buttons are hidden
- internal submit success/error UI states are hidden
This mode is designed for external state management and custom submission flows.
Controlled mode
Use composables and pass model and schema manually.
<FormForgeRenderer
:schema="form.schema"
:model-value="form.state"
:zod-schema="form.zodSchema"
@update:model-value="form.replaceState"
/>
Schema resolution priority
- if
schemais provided, it is used directly - otherwise, schema is loaded from
form-key
Typical features
- progress display
- validation alerts
submittedanderrorevents
Validation API (standalone and external model)
FormForgeRenderer now exposes validation helpers through the component ref:
validate(options?)validateField(name)clearErrors(path?)getErrors(path?)
<script setup lang="ts">
const renderer = ref<InstanceType<typeof FormForgeRenderer> | null>(null)
async function runValidation(): Promise<void> {
const result = await renderer.value?.validate()
if (!result?.valid) {
console.log(renderer.value?.getErrors())
}
}
</script>
<template>
<FormForgeRenderer ref="renderer" form-key="my-form" />
</template>
Validation props:
validateOnvalidateOnBlur
In external v-model integrations, blur-based validation is handled explicitly per field (focusout path) for more predictable standalone behavior.
Integrating in a custom parent form
When FormForge data is embedded in a parent form, block parent submit until renderer validation passes.
<script setup lang="ts">
import { z } from 'zod'
const renderer = ref<InstanceType<typeof FormForgeRenderer> | null>(null)
const formData = ref<Record<string, unknown>>({})
const parentSchema = z.object({
title: z.string().min(1),
data: z.record(z.string(), z.unknown())
})
async function onParentSubmit(): Promise<void> {
const rendererResult = await renderer.value?.validate()
if (!rendererResult?.valid) {
return
}
// continue with your external submit flow
}
</script>
<template>
<form @submit.prevent="onParentSubmit">
<FormForgeRenderer
ref="renderer"
form-key="my-form"
v-model="formData"
:validate-on-blur="true"
/>
</form>
</template>
Use an object schema for embedded FormForge payloads (z.record(...)), not z.string().