In Vue, you mount @usefillo/dom into an element the component owns and destroy it when the component unmounts.
Install the DOM package
npm install @usefillo/domMount and destroy the form
<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from "vue";
import { renderForm, type FilloDomForm } from "@usefillo/dom";
import "@usefillo/dom/styles.css";
const root = ref<HTMLElement | null>(null);
let form: FilloDomForm | undefined;
onMounted(() => {
if (!root.value) return;
form = renderForm(root.value, {
formId: "your-published-form-id",
onSubmitted: (responseId) => console.info("Fillo response", responseId),
});
});
onBeforeUnmount(() => form?.destroy());
</script>
<template>
<section aria-labelledby="feedback-title">
<h2 id="feedback-title">Product feedback</h2>
<div ref="root" />
</section>
</template>If you wrap this pattern in a shared utility, you can also infer the handle type as ReturnType<typeof renderForm>.
Handle route reuse
When a route reuses the component for a different form ID, destroy the current instance before mounting the next one. Don't let Vue touch the children inside the renderer root — pass new values through the supported renderer or controller APIs instead.
Verify the lifecycle
Test the initial load, a published-form 404, navigating away mid-upload, coming back, validation, and a successful submission. The public published-form path needs no key.
Try it
Start with a prompt and your coding agent builds the first form, staged for your review — or open the editor.
Related
- Contact example: Inspect the native form behavior mounted by this component.
- Embed quickstart: Review the DOM renderer and standalone options.
- SDK reference: Inspect renderer methods and cleanup behavior.
- Styling: Use CSS variables, slots, and state attributes.