Structure
Structure
This page covers document navigation and logical structure: outlines (bookmarks), tables of contents, named destinations, and the tagged structure tree used for accessibility and reflow.
Outlines (Bookmarks)
Document.GetOutlines() returns the current outline tree as OutlineItem[]
([] when there is no /Outlines); Document.SetOutlines() replaces it —
passing [] removes the outline entirely. Each OutlineItem has a Title,
a Dest (a page number or a named destination), optional Children for
nesting, and styling (Color, Bold, Italic, Open).
const items: OutlineItem[] = sections.map((s) => {
const item: OutlineItem = { Title: s.title, Dest: { name: s.dest } };
if (s.subtype === 'sales') {
item.Open = true;
item.Children = ['Pasta', 'Pizza', 'Antipasti']
.map((cat) => ({ Title: cat, Dest: { name: s.dest } }));
}
return item;
});
doc.SetOutlines(items);Table of Contents
Page.AddTOC() renders a list of TOCEntry objects — each with a title
and a target page number — into a rectangle on a page, with wrapped
titles, dot leaders, and right-aligned page labels. It returns an
AddTOCResult reporting how many entries were drawn and, when the box is
too small, the remainder that did not fit.
page.AddTOC(
sections.map((s, i) => ({ title: `${i + 1}. ${s.title}`, page: s.page.Number })),
[72, 160, 400, 400],
{ font: 'Helvetica', fontSize: 13, rowGap: 18 },
);Named Destinations
Document.GetNamedDestinations() returns every named destination — merging
the /Names /Dests name tree and the legacy /Dests dictionary — as
{ name, dest } pairs, where dest is a PageDest ({ page, view }).
These are the same named targets an OutlineItem.Dest or a link annotation
can reference by name instead of an explicit page number.
const destNames = new Set(doc.GetNamedDestinations().map((d) => d.name));
for (const { name, dest } of doc.GetNamedDestinations()) {
console.log(name, '-> page', dest.page);
}Tagged Structure Tree
Document.AutoTag() infers and authors a /StructTreeRoot from page
layout — headings by font-size clustering, paragraphs by text blocks, tables
by ruling geometry, and per-image /Figure vs. /Artifact decisions — and
returns an AutoTagReport with counts for each element kind.
Document.GetStructTree() reads back the resulting StructTreeRoot, or
null when the document is untagged.
const report = doc.AutoTag({ lang: 'en-US', title: 'Quarterly Report', tables: true });
console.log(report.headings, report.paragraphs, report.tables, report.figures);
const tree = doc.GetStructTree();
console.log(tree ? tree.GetText() : '(no structure tree)');Content added after AutoTag() has already run — a page filled in
afterward, for example — is not covered by that pass and will not
double-tag. StructTreeRoot.Append() and StructElement.MarkContent() are
the manual authoring API alongside the heuristic one: Append() adds a
child element of a given type, and MarkContent() marks a page region as
belonging to that element.
Tips and Best Practices
- Run
Document.AutoTag()once, after page content is final — it does not re-tag content added afterward, so hand-tag anything added later withStructTreeRoot.Append()/StructElement.MarkContent(). - Pass
opts.titletoAutoTag()— it also sets/ViewerPreferences /DisplayDocTitle, which PDF/UA requires alongside a document title. - An
OutlineItem.Destcan target either an explicit page or a named destination ({ name: '...' }) — use named destinations when the target page number might shift as content changes. - Check
AddTOCResult.remainderwhen auto-pagination is off — a table of contents box too small for every entry silently stops drawing rather than overflowing the box.
Common Issues
| Issue | Cause | Fix |
|---|---|---|
Document.GetStructTree() returns null | The document has not been tagged | Call Document.AutoTag() or Document.CreateStructTree() first |
| An outline item’s link does not resolve | Its Dest names a destination that does not exist in Document.GetNamedDestinations() | Confirm the named destination exists, or use an explicit page Dest instead |
Page.AddTOC() stops before the last section | The target rect is too small for every entry and autoPaginate is off | Enlarge the rect, pass autoPaginate: true, or handle AddTOCResult.remainder |
Content added after AutoTag() is missing from the structure tree | AutoTag() only tags content present when it ran | Hand-tag the later content with StructTreeRoot.Append() / StructElement.MarkContent() |
FAQ
How do I add bookmarks to a PDF?
Build an array of OutlineItem objects (Title, Dest, optional
Children) and pass it to Document.SetOutlines().
Can a table of contents span multiple pages?
Yes — pass autoPaginate: true in Page.AddTOC()’s options, or check
AddTOCResult.remainder and call AddTOC() again on a new page for
whatever did not fit.
How do I make a PDF accessible (tagged)?
Call Document.AutoTag(), which infers headings, paragraphs, tables, and
figures from page layout. For content added afterward, or where the
heuristic result needs correction, use StructTreeRoot.Append() and
StructElement.MarkContent() directly.
What is the difference between a page-number destination and a named destination?
A page-number destination (PageDest) targets an explicit 1-based page. A
named destination (NamedDest) targets a name that a viewer resolves
through the document’s own named-destination tables — useful when the
target page might move.
API Reference Summary
| Class/Method | Description |
|---|---|
Document.GetOutlines() / Document.SetOutlines() | Read or replace the document outline (bookmark) tree |
OutlineItem | One outline node: Title, Dest, optional Children |
Page.AddTOC() | Render a table of contents into a page rectangle |
TOCEntry / AddTOCResult | A TOC row’s data, and the outcome of drawing it |
Document.GetNamedDestinations() | List every named destination in the document |
Document.AutoTag() | Infer and author a tagged structure tree from page layout |
Document.GetStructTree() / Document.CreateStructTree() | Read or create the document’s StructTreeRoot |
StructTreeRoot.Append() / StructElement.Append() / StructElement.MarkContent() | Manually author or extend the structure tree |