Importing and exporting annotations in XFDF

XML Forms Data Format (XFDF) is an XML-based standard from Adobe XFDF (ISO 19444-1:2016) for encoding annotations and form field values. It’s compatible with Adobe Acrobat and several other third-party frameworks.

XFDF has various limitations. In most cases, using the Instant JSON format will result in a smaller file and better synchronization.

Importing XFDF

You can import annotations in XFDF format in both operational modes of Nutrient Web SDK:

  • When using Web SDK with Document Engine (server-side processing)

  • When using Web SDK only (client-side processing)

Importing XFDF with Document Engine

Nutrient Web SDK with Document Engine supports importing annotations from an XFDF file when uploading a document using the /api/documents endpoint. Send a multipart/form-data POST request, including the PDF and the XFDF file, to import the annotations in the given PDF file. This will replace all existing annotations in the uploaded PDF with the annotations from the uploaded XFDF file. If you want to add annotations to already existing ones instead of replacing them, set keep_current_annotations to true:

Request

POST /api/documents
Content-Type: multipart/form-data; boundary=customboundary
Authorization: Token token="<secret token>"

--customboundary
Content-Disposition: form-data; name="file"; filename="Example Document.pdf"
Content-Type: application/pdf

<PDF data>
--customboundary
Content-Disposition: form-data; name="attachment"; filename="attachment.xfdf"
Content-Type: application/vnd.adobe.xfdf

<annotations data>
--customboundary
Content-Disposition: form-data; name="keep_current_annotations"

true
--customboundary--

For an in-depth example, refer to the importing and exporting annotations with Document Engine guide.

Importing XFDF when only using Web SDK

To import XFDF when using Nutrient Web SDK, use the Configuration#XFDF option.

In addition to the Configuration#XFDF option, you can also set the Configuration#XFDFKeepCurrentAnnotations flag. This flag will make sure annotations that are already in the source PDF are kept and not replaced with those defined in the XFDF:

PSPDFKit.load({
  document: "https://your-server.com/some/document.pdf",
  XFDF: `<?xml version="1.0" encoding="UTF-8"?><xfdf xml:space="preserve" xmlns="http://ns.adobe.com/xfdf/"> ..`
});

Exporting to XFDF

You can export annotations in the document in XFDF format in both operational modes. When using Web SDK with Document Engine, export XFDF using the REST API or the client-side API. When only using Web SDK, export XFDF using the client-side API.

Exporting XFDF using REST API

When using Nutrient Web SDK with Document Engine, export the current annotations of a document as an XFDF file using a GET request to /api/documents/:document_id/document.xfdf. To get the current annotation of a document’s layer, send a GET request to /api/documents/:document_id/layers/:layer_name/document.xfdf:

Request

GET /api/documents/:document_id/document.xfdf
Authorization: Token token="<secret token>"
$ curl "http://localhost:5000/api/documents/abc/document.xfdf" \
   -H "Authorization: Token token=<secret token>"

Response

HTTP/1.1 200 OK
Content-Type: application/vnd.adobe.xfdf

<XFDF data>

Exporting XFDF using the client-side API

In both operational modes, you can export the XFDF file through the client-side API using the Instance#exportXFDF method:

instance.exportXFDF().then((xfdf) => {
  console.log(xfdf); // => <?xml version="1.0" encoding="UTF-8"?><xfdf xml:space="preserve" xmlns="http://ns.adobe.com/xfdf/"> ...
});

XFDF works seamlessly with the annotation API. If you want to persist annotations whenever changes are made, we recommend using the annotations.didSave event. This event will be triggered automatically and can be configured using Configuration#autoSaveMode.

Saving annotations when using only Web SDK

When using only Web SDK, saving annotations doesn’t send them to a backend server. Instead:

  • Annotations are stored in memory after a save operation.

  • To persist annotations, you must either:

Unsaved annotations won’t be exported. This behavior mirrors how annotations are handled when using a server.

instance.addEventListener("annotations.didSave", async () => {
  const xfdf = await instance.exportXFDF();
  await fetch("https://your-server.com/xfdf", {
    method: "post",
    headers: {
      "Content-Type": "application/vnd.adobe.xfdf"
    },
    body: xfdf
  });
});

Exporting annotations to XFDF using Adobe Acrobat

To export annotations from Adobe Acrobat into XFDF format:

  1. Open the Comments tool from the sidebar.

  1. Click the three dots menu and select Export All To Data File.

  1. In the export dialog:

    • Set the file type to Acrobat XFDF Files at the bottom.

    • Select the directory where you want to save the XFDF file to, and enter a name for the file.

    • Click Save.

After exporting, you’ll have a file with an .xfdf extension.

Importing annotations to XFDF using Adobe Acrobat

To import annotations from Adobe Acrobat into XFDF format:

  1. Open the Comments tool from the sidebar.

  1. Click the three dots menu and select Import Data File.

  1. Choose the .xfdf file you want to import, and click Select.

After import, Adobe Acrobat will place the annotations onto the document.

Adobe Acrobat error conditions

Error description Screenshot
Damaged/missing document body
Damaged/missing description tag
Missing document flag