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.

On top of that built-in experience, you can 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.

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

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.

Form State

Fill the PDF on the left to watch the values update live.

Fields
0
Filled
0
Changes
0

Waiting for form fields...

Accessing the Form Plugin

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

import { FormPlugin } from '@embedpdf/react-pdf-viewer'; const registry = await viewerRef.current?.registry; const formPlugin = registry?.getPlugin<FormPlugin>('form')?.provides(); const scope = formPlugin?.forDocument('form-doc');

Listening for Field Changes

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

const unsubscribeReady = scope.onFormReady((fields) => { console.log('Fields discovered:', fields.length); console.log('Initial values:', scope.getFormValues()); }); const unsubscribeChange = scope.onFieldValueChange((event) => { console.log('Changed widget:', event.annotationId); console.log('Updated values:', scope.getFormValues()); });

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():

const scope = formPlugin?.forDocument('form-doc'); await scope?.setFormValues({ First_Name: 'Jane', Last_Name: 'Doe', Email_Address: 'jane.doe@example.com', }).toPromise();

Saving the Filled PDF

Filled form values are included when you export the document:

const exportPlugin = registry?.getPlugin('export')?.provides(); const pdfBytes = await exportPlugin ?.forDocument('form-doc') .saveAsCopy() .toPromise();
ℹ️

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.