---
title: "Add a form to Vue"
description: "Mount and clean up the framework-agnostic Fillo DOM renderer inside a Vue component."
order: 13
type: "guide"
topic: "Frameworks"
tags:
  - "Vue"
  - "DOM renderer"
  - "embed"
  - "lifecycle"
updated: "2026-07-15"
---

In Vue, you mount `@usefillo/dom` into an element the component owns and destroy it when the component unmounts.

## Install the DOM package

```bash
npm install @usefillo/dom
```

## Mount and destroy the form

```vue
<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](/start?from=guide-vue-form) and your coding agent builds the first form, staged for your review — or [open the editor](/new).

## Related

- [Contact example](/examples#contact): Inspect the native form behavior mounted by this component.
- [Embed quickstart](/docs/embed): Review the DOM renderer and standalone options.
- [SDK reference](/docs/reference): Inspect renderer methods and cleanup behavior.
- [Styling](/docs/styling): Use CSS variables, slots, and state attributes.
