PDF/A
Archival output that validators accept
Render a PDF/A document with pdfa.
import { } from "takumi-pdf";
const = await (, {
: "3b",
});Conforming output includes an sRGB output intent and XMP metadata. Fonts are always embedded and subset, with or without PDF/A.
Levels
| Level | PDF version | What it adds |
|---|---|---|
"2b" | PDF 1.7 | Basic conformance. |
"2u" | PDF 1.7 | 2b plus guaranteed Unicode mapping. |
"2a" | PDF 1.7 | 2u plus a tagged structure tree. |
"3b" | PDF 1.7 | 2b plus arbitrary file attachments. |
"3u" | PDF 1.7 | 2u plus arbitrary file attachments. |
"3a" | PDF 1.7 | 3u plus a tagged structure tree. |
"4" | PDF 2.0 | The PDF 2.0 revision of the standard. |
"4f" | PDF 2.0 | 4 plus arbitrary file attachments. |
The u levels add no output cost. Takumi always writes ToUnicode maps.
PDF/A-3 and PDF/A-4f allow arbitrary file attachments. ZUGFeRD and Factur-X electronic invoices expect "3b". See Attachments.
PDF/A-1 is not offered. It prohibits transparency.
Validation runs during rendering. When a document cannot conform, the render fails with the violated rule instead of writing a broken file.
Every level, and PDF/UA-1, passes veraPDF, the reference validator.
Tagged output
tagged defaults to true. Tagged output mirrors Chromium's print-to-PDF.
Set tagged: "ua1" to also validate against PDF/UA-1:
import { } from "takumi-pdf";
const = await (, {
: "2a",
: "ua1",
: "en",
: {
: "Annual report",
: "2026-08-06",
},
});The structure tree comes from the HTML semantics:
| HTML | |
|---|---|
h1–h6 | Hn with the heading text as title |
p, bare text | P |
img | Figure with the alt text |
img with alt="" | artifact (decorative, no element) |
a | Link, holding the link annotation |
ul, ol, li | L, LI, LBody |
strong, em, code | Strong, Em, Code |
| page headers and footers | artifacts |
Heading levels come from nesting, not the tag name. A document that starts with h2 gets an H1. A jump from h1 to h4 becomes H1 then H2. PDF/UA rejects a sequence that skips a level or starts below H1. HTML written for visual styling does this all the time.
Tables are missing from that list. <table> markup is not supported. A table built out of flex rows carries no Table, TR or TH elements, so a screen reader cannot navigate it by row and column. The file still passes PDF/UA-1. The validator checks the tags that are there, not the ones the content deserves.
Set tagged: false to skip the tree when file size matters more than accessibility.
Invalid combinations are TypeScript type errors. pdfa: "2a" and pdfa: "3a" forbid tagged: false. pdfa: "4" forbids tagged: "ua1", because PDF/UA-1 is PDF 1.7-only and PDF/A-4 is PDF 2.0. The 2 levels and "4" forbid attachments. Use "4f" for attachments in PDF 2.0. See Attachments.
Validators require inputs the renderer cannot supply:
langis the document language. A-levels and PDF/UA require it.metadata.titleis required by PDF/UA.metadata.creationDateis required by thealevels. Use UTC"YYYY-MM-DD"or"YYYY-MM-DDTHH:MM:SS". A fixed date keeps output byte-identical across runs.
PDF/UA also requires a document outline. Takumi generates it from headings.
Last updated on