Links, outline & metadata
Clickable hyperlinks, a table of contents, bookmarks, and document properties.
Add links with <a href>, bookmarks with outline, and document properties with metadata.
Hyperlinks
Anchors with an href become clickable link annotations. They appear on every page that their box touches:
import { } from "takumi-pdf";
const = await (
<>
Pay online at < ="https://example.com/pay/1042">example.com/pay/1042</>.
</>,
);Inline anchors annotate each text run. A link that wraps across lines stays clickable on both lines. Block-level anchors annotate their entire box.
http, https, mailto and tel links open outside the document. An href starting with # points inside it instead, to the element carrying that id:
import { } from "takumi-pdf";
const = await (
<>
< ="#appendix">Jump to the appendix</>
< ="appendix">Appendix</>
</>,
);Internal links jump to the target element. Unresolved fragments and unsupported URL schemes are omitted.
Table of contents
<TargetPageNumber /> prints the page number of an internal link target. Put it inside an <a href="#id">, or pass href to the primitive to create its own link. HTML input can use the targetPageNumber class on an element inside the link.
import { } from "takumi-pdf";
import { } from "takumi-pdf/primitives";
const = await (
<>
< ="#results" ="flex items-baseline gap-2">
<>Results</>
< ="flex-1 border-b border-dotted border-gray-400" />
< ="w-8 shrink-0 text-right" />
</>
< ="results" ={{ : "page" }}>
Results
</>
</>,
);The stretched span draws the dot leader. Counter styles work here too, so format="upper-roman" prints IV. See Counter styles for the full list.
A fragment naming no element prints nothing. This follows the rule links already use.
Reserve space for page numbers
A page number exists only after pagination. Takumi paginates, fills the numbers in, and lays the document out again. A number that widens its line can move a page break, and the moved break can renumber the entry. The render repeats this up to three times, then keeps what it has.
The example reserves width with w-8 shrink-0 text-right. Increase it if your document needs more digits. This prevents page numbers from changing the entry width during layout.
Headers and footers are laid out per page, outside this loop. A <TargetPageNumber /> in a band renders nothing.
Outline
Set outline: true to build PDF bookmarks from h1βh6. Deeper headings nest under the previous shallower heading:
import { } from "takumi-pdf";
const = await (, { : true });Clicking a bookmark jumps to the page and position of its heading.
Document metadata
metadata fills the PDF document properties. lang also sets the metadata language:
import { } from "takumi-pdf";
const = await (, {
: "en",
: {
: "Annual report 2026",
: "Consolidated results for fiscal year 2026",
: ["Acme Inc."],
: ["annual report", "2026"],
: "acme-reporting",
},
});Metadata fields are optional for ordinary PDF output. PDF/A and PDF/UA require some fields. Use a fixed creationDate when you need reproducible output.
Last updated on