Generate a table of contents for a PDF
Generating a table of contents for a PDF means finding the document's headings and turning them into navigation: a bookmark outline in the reader's sidebar and, optionally, a contents page at the front. This page detects headings automatically by comparing each line's font size to the body text's median size, builds a two-level outline from the results, writes it into the PDF's bookmark dictionary, and can prepend a clickable contents page whose entries jump to the right pages with internal go-to links. Everything runs in your browser; the file is never uploaded.
How it works
A PDF has no concept of "heading" — unlike HTML, there is no h1 or h2 tag. What it does have is precise typography: every run of text carries a font name and a point size. This tool exploits that. It first extracts the text layer of every page with pdf.js and collects the font size of each line. The median of all those sizes is taken as the body-text size — the median rather than the mean, because a few very large title lines would drag an average upward, while the median stays anchored to the size most of the document is actually set in.
Any line set significantly larger than that median is a heading candidate. The candidates' sizes are then clustered: the largest size that recurs across the document becomes heading level one, and the next distinct size down becomes level two. Single-line-per-page filtering and length limits weed out things like giant drop caps or a full paragraph accidentally set large. The result is an ordered list of entries, each with its text, level, page number, and vertical position on the page.
That list is written into the file two ways. First, as a genuine outline: PDF bookmarks are a linked tree of outline dictionaries, each holding a title string and a destination (page reference plus coordinates), and this tool builds that tree with pdf-lib so the outline appears in the sidebar of Acrobat, Preview, Firefox, and every conforming reader. Second, optionally, as a visible contents page inserted before page 1: each entry is laid out with its page number and covered by an internal go-to link annotation, so clicking a line jumps straight to the heading it names. Page numbers on the contents page refer to the original numbering, and the outline destinations are adjusted so they still land correctly after the extra page shifts everything by one.
Because detection is typographic rather than semantic, review the result before distributing it: decorative large text can be picked up as a heading, and chapters and sections set at the same point size cannot be separated into two levels. For fine control — or for documents where detection misses — the manual Bookmark PDF tool lets you type each entry yourself.
Illustrative example: a 58-page project handbook
Illustrative scenario, not a recorded benchmark. File sizes, timings and results depend on the input and device. Try the reproducible samples.
A 58-page internal handbook (1.8 MB, exported from a word processor years ago with no bookmarks) has body text at 11 pt, chapter titles at 20 pt, and section headings at 14 pt. The tool computes the median line size as 11 pt, flags 9 lines at 20 pt and 41 lines at 14 pt as candidates, and clusters them into two levels: 9 chapters, 41 sections. Analysis of all 58 pages takes about 6 seconds on a mid-range laptop.
The generated outline shows one false positive — the 20 pt cover line "CONFIDENTIAL — INTERNAL USE" was picked up as a chapter — which takes one click to delete in the review list before writing. With the clickable contents page enabled, the output is a 59-page, 1.9 MB file: the new page 1 lists all 50 entries with their page numbers, each line linked, and the sidebar outline shows the same two-level tree. A reader looking for "7.3 Expense approval" now reaches it in one click instead of scrolling through 58 pages.
Frequently asked questions
How can I generate a table of contents for a PDF automatically?
Load the PDF into a tool that reads the text layer and compares each line's font size to the document's body-text median: lines set noticeably larger are treated as headings. This page does exactly that in your browser, then writes the detected headings as a bookmark outline and, if you want, a clickable contents page at the front.
Does this work on scanned PDFs?
No — heading detection needs a real text layer with font-size information, and a scanned page is just an image. Run the scan through OCR first to add a text layer, then generate the contents.
Why did the tool pick up text that is not a heading?
Detection is purely size-based, so any decorative large text — a cover title, a pull quote, a large page number — can be mistaken for a heading. Review the generated outline and delete or rename entries before you share the file.
Can it tell chapter headings apart from section headings?
It builds two levels: the largest recurring heading size becomes level one and the next distinct size becomes level two. Headings set at the same point size cannot be told apart, so a document that styles chapters and sections identically will come out as one flat level.
Are the bookmarks real PDF bookmarks or just a text page?
Both are real: the outline is written into the PDF's bookmark (outline) dictionary, so it appears in the sidebar of Adobe Acrobat, Preview, and every standard reader. The optional contents page uses internal go-to link annotations, so each line is clickable and jumps to its page.
Is my document uploaded anywhere during the process?
No — the PDF is parsed, analyzed, and rewritten entirely by JavaScript running on your device, and it never leaves your computer. You can disconnect from the internet after the page loads and the tool still works.