PDF/A and PDF/UA
Configure archival output, document tags, and accessibility validation.
Use pdfa for archival output and tagged for document structure and PDF/UA validation. The selected standard determines which metadata and attachments are allowed.
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.
Validate your generated document with veraPDF. Internal checks do not replace reviewing reading order, alternative text, or the meaning of your content.
Tagged output
tagged defaults to true, which writes a structure tree from the document's HTML semantics. This alone does not request PDF/UA validation.
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) |
figure, figcaption | one Figure holding a Caption |
a | Link, holding the link annotation |
ul, ol, li | L, LI, LBody |
strong, em, code | Strong, Em, Code |
table, caption | Table holding a Caption |
thead, tbody, tfoot | THead, TBody, TFoot |
tr, th, td | TR, TH with Scope, TD |
| page headers and footers | artifacts |
Heading levels are normalized in the structure tree. A document starting with h2 gets H1, and a jump from h1 to h4 becomes H1 followed by H2. Use meaningful heading levels in your source even when their visual sizes differ.
Header cells carry a Scope attribute: Column inside thead, Row elsewhere. A scope attribute on the cell overrides it. rowspan and colspan become RowSpan and ColSpan attributes. A table that spans pages stays one Table element. The repeated header band is marked as an artifact.
Table elements follow the rendered layout, like the rest of the tree. A <table> whose display is overridden gets none, and neither does a table built from flex rows. Screen readers cannot navigate those by row or column, and the file still passes PDF/UA, because the validator only checks the tags that are there.
Set tagged: false only when you do not need a structure tree and the selected standard permits it.
PDF/UA-2
tagged: "ua2" validates against PDF/UA-2 instead. The standard is PDF 2.0 only, so it pairs with pdfa: "4", pdfa: "4f", or plain PDF.
import { } from "takumi-pdf";
const = await (, {
: "4",
: "ua2",
: "en",
: {
: "Annual report",
: "2026-08-08",
},
});Links and outline entries target structure elements, not page positions. Reading order survives when a viewer follows one.
Compatible options
Invalid combinations are TypeScript type errors. PDF/UA-1 uses PDF 1.7. PDF/A-4 and PDF/UA-2 use PDF 2.0. The two generations never mix.
pdfa | tagged | attachments |
|---|---|---|
| unset | false, true, "ua1", "ua2" | yes |
2b, 2u | false, true, "ua1" | no |
2a | true, "ua1" | no |
3b, 3u | false, true, "ua1" | yes |
3a | true, "ua1" | yes |
4 | false, true, "ua2" | no |
4f | false, true, "ua2" | yes |
See Attachments.
Validators require inputs the renderer cannot supply:
langis the document language. A-levels and PDF/UA require it. PDF/UA-2 fails the render without it. A passage in another language needs its ownlangattribute.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