EmbedPDF

Forms

The PDFViewer includes the form plugin by default, so PDFs with AcroForm fields become interactive automatically. Users can type into text fields, toggle checkboxes, select radio buttons, and choose dropdown values directly in the built-in viewer UI.

You can also access the form plugin through the viewer registry to read field values, react to changes, or populate the form from your own application data.

Configuration

There is no special form configuration required right now. If you load a PDF that contains form fields, the viewer will render them automatically.

<template> <PDFViewer :config="{ src: '/form.pdf', export: { defaultFileName: 'filled-form.pdf' } }" /> </template>
ℹ️

The built-in viewer keeps the form category locked by default, which makes widgets immediately fillable. If you switch into form authoring mode from the viewer UI, the lock is lifted so widgets can be selected and edited like annotations.

Reading Form State

You can subscribe to form lifecycle events and inspect the current field values through the form plugin API.

Accessing the Form Plugin

Use the viewer registry to get the form capability for a specific document:

<script setup lang="ts"> import { ref } from 'vue'; import { PDFViewer, type PluginRegistry, type FormPlugin } from '@embedpdf/vue-pdf-viewer'; const registry = ref<PluginRegistry | null>(null); const handleReady = (r: PluginRegistry) => { registry.value = r; }; const formScope = () => { const formPlugin = registry.value?.getPlugin<FormPlugin>('form')?.provides(); return formPlugin?.forDocument('form-doc'); }; </script> <template> <PDFViewer @ready="handleReady" :config="{ src: '/form.pdf' }" /> </template>

Listening for Field Changes

Once you have a document-scoped form API, you can read all values and subscribe to updates:

<script setup lang="ts"> const scope = formScope(); scope?.onFormReady((fields) => { console.log('Fields discovered:', fields.length); console.log('Initial values:', scope.getFormValues()); }); scope?.onFieldValueChange((event) => { console.log('Changed widget:', event.annotationId); console.log('Updated values:', scope.getFormValues()); }); </script>

Programmatically Setting Values

The same API can be used to pre-fill a form from external data, restore saved values, or clear a form back to a known state.

Auto Fill and Reset

Pass a field-name-to-value map to setFormValues():

<script setup lang="ts"> const fillForm = async () => { const scope = formScope(); await scope?.setFormValues({ First_Name: 'Jane', Last_Name: 'Doe', Email_Address: 'jane.doe@example.com', }).toPromise(); }; </script>

Saving the Filled PDF

Filled form values are included when you export the document:

<script setup lang="ts"> const saveFilledPdf = async () => { const exportPlugin = registry.value?.getPlugin('export')?.provides(); const pdfBytes = await exportPlugin ?.forDocument('form-doc') .saveAsCopy() .toPromise(); }; </script>
ℹ️

Radio buttons still expect the exact export value defined in the PDF. Checkboxes are more forgiving: pass "Off" to clear them, and any other string will be normalized to the widget’s checked export value.

Last updated on March 25, 2026

Need Help?

Join our community for support, discussions, and to contribute to EmbedPDF's development.