Markdown Editors: Generate Clickable PDF TOCs (Finally)

Why Doesn't My Markdown PDF Have a Clickable Table of Contents?

You wrote a 47-page technical spec in your browser-based markdown editor. You hit "Export to PDF." You opened the file, scrolled to page 3 where your table of contents sits, and clicked "Section 4.2 — Authentication Flow." Nothing happened. The cursor didn't move. The page didn't jump. You clicked again. Still nothing.

Here's what went wrong: your markdown editor generated a visual table of contents — a list of headings that looks like a TOC but carries no internal link metadata. The PDF renderer printed text on a page. It did not wire up anchor destinations.

This is the single most common complaint among technical writers who use browser-based markdown editors for client deliverables. The TOC looks perfect in the browser preview. It even clicks fine in the preview pane. But the moment you export to PDF, the interactivity evaporates.

The good news? This is fixable. And you don't need to switch editors, install a local LaTeX toolchain, or abandon your browser-based workflow. You need to understand what happens between your markdown source and the final PDF byte stream — and then configure the right layer.

How Do Browser-Based Markdown Editors Generate a Table of Contents?

Most browser-based markdown editors — whether you're using StackEdit, HackMD, Dillinger, or a self-hosted instance of Editor.md — generate a TOC through one of two mechanisms:

Markdown Extension Syntax

Some editors support a TOC extension token. You type [TOC] or {{toc}} on its own line, and the editor's parser scans your document for ATX headings (##, ###, etc.), then injects an unordered list of anchor links at that position. In the browser preview, each list item is an <a href="#section-id"> element pointing to the heading's generated ID.

JavaScript DOM Injection

Other editors skip markdown extensions entirely. Instead, a JavaScript module runs after the initial render, queries the preview pane for h1 through h6 elements, extracts their text and ID attributes, and builds a TOC container dynamically. This approach is more flexible — the editor can update the TOC in real time as you type — but it introduces a critical weakness for PDF export.

And that weakness is where our story gets interesting.

What Makes a TOC Clickable Inside a PDF File?

A clickable TOC in a PDF is not an HTML anchor link. It is not a JavaScript click handler. It is a specific PDF data structure called a named destination combined with a GoTo action.

Here's the simplified anatomy: when you click "Section 4.2" in a working PDF table of contents, the PDF reader looks up a destination object — essentially a pointer that says "page 31, y-coordinate 450" — and jumps there. The text "Section 4.2" is wrapped in a link annotation object that carries the GoTo action referencing that destination.

This means two things must happen during PDF generation:

  1. Each heading must be registered as a named destination with a unique identifier and a page coordinate.
  2. Each TOC entry must be linked to that destination via a GoTo action, not just styled to look like a link.

If your browser-based markdown editor relies on an HTML-to-PDF conversion layer — and most do — the conversion layer is responsible for translating HTML anchor links into PDF GoTo actions. If that layer is misconfigured, skipped, or simply doesn't support destination mapping, you get a dead TOC.

Which PDF Engine Does Your Browser-Based Markdown Editor Actually Use?

This is the question nobody asks, and it's the one that determines whether your TOC will work. Browser-based markdown editors typically use one of three PDF generation strategies:

Strategy 1: Browser Print Dialog (window.print)

The editor opens a print-optimized view and calls window.print(). The browser's native print-to-PDF engine handles the conversion. This is the simplest approach, and it is also the one most likely to produce a dead TOC. Browser print engines vary wildly: Chrome's print-to-PDF preserves some internal links, Firefox's does not, and Safari's is unpredictable. If your editor's "Export to PDF" button feels suspiciously fast — like it opens a print dialog instead of generating a file — you're probably here.

Strategy 2: Client-Side JavaScript PDF Libraries

Some editors bundle a library like jsPDF, pdfmake, or html2pdf.js. These libraries run entirely in the browser and construct the PDF byte stream in JavaScript. The better ones — html2pdf.js with the right configuration — can translate HTML anchor links into PDF GoTo actions. The weaker ones render each page as a canvas image and embed it in the PDF, which means zero clickable anything.

Strategy 3: Server-Side Rendering

If your editor has a backend component — think HackMD/CodiMD with a Node server, or any editor that sends your markdown to a server for processing — it may use a headless browser (Puppeteer), a dedicated converter (Pandoc), or a typesetting engine (wkhtmltopdf, WeasyPrint). These server-side tools generally produce the most reliable clickable TOCs because they have full control over the PDF object tree.

Find out which strategy your editor uses. Check the documentation, inspect network requests when you click export, or read the source if it's open source. This single piece of information tells you whether you need a workaround or just a configuration change.

How Do You Configure a Clickable TOC for PDF Export?

Let's walk through a concrete configuration. I'll use the most common scenario: a browser-based markdown editor that uses html2pdf.js or a similar client-side library, with HTML anchor links in the TOC.

Step 1: Ensure Headings Have Stable IDs

Your markdown parser must generate id attributes on every heading element. Most modern parsers do this automatically by slugifying the heading text. Verify by inspecting the preview pane DOM: right-click a heading, select "Inspect," and confirm the <h2> tag has an id="authentication-flow" attribute (or similar). If IDs are missing, your parser configuration needs to enable heading anchors — sometimes called "toc" or "anchorLinks" in marked.js, markdown-it, or similar parser options.

Step 2: Generate the TOC from Heading Data

Use the editor's TOC token ([TOC]) or a plugin that builds the TOC from the parsed heading list. Each TOC entry must be an anchor tag with an href matching the heading's ID: <a href="#authentication-flow">Authentication Flow</a>. Confirm these links work in the browser preview before proceeding — if they don't click in the preview, they won't click in the PDF.

Step 3: Configure the PDF Library to Preserve Links

This is where most people get stuck. If your editor uses html2pdf.js, the default configuration strips interactive elements. You need to pass options that explicitly enable link preservation. The key configuration looks like this:

html2pdf().set({ pagebreak: { mode: ['css', 'legacy'] }, enableLinks: true, jsPDF: { unit: 'mm', format: 'a4' } });

The enableLinks: true flag tells the underlying jsPDF engine to scan the rendered HTML for anchor elements and create corresponding GoTo actions in the PDF. Without this flag, links are invisible to the PDF engine.

Step 4: If Using Print-to-PDF, Add CSS Print Hints

For editors that use window.print(), you can improve link preservation with CSS. Add @media print { a[href]:after { content: ""; } } to suppress URL suffixes that some browsers append, and ensure your TOC links use href="#fragment" syntax rather than full URLs. Chrome's print-to-PDF respects internal fragment links more reliably than absolute URLs.

What Breaks Clickable TOCs Even When Everything Looks Right?

You followed every step. The preview clicks. The configuration is correct. The PDF still has a dead TOC. Here are the four culprits I see most often in browser-based markdown editors:

Culprit 1: Heading IDs Contain Invalid Characters

If your heading text contains emojis, non-Latin characters, or consecutive spaces, the slugify function may produce IDs that are valid HTML but invalid as PDF named destinations. PDF destinations have stricter naming rules. Replace problematic headings with ASCII-friendly text, or patch the slugify function to sanitize IDs to [a-zA-Z0-9_-] only.

Culprit 2: The TOC Is Rendered After PDF Pagination

Some editors build the TOC element after the PDF library has already paginated the content. The TOC appears in the PDF, but its link annotations were never registered because the PDF's page structure was finalized before the TOC links existed. The fix: ensure TOC generation runs as a pre-render hook, before the PDF library processes the document.

Culprit 3: Page Breaks Split TOC Entries from Their Targets

If a heading falls at the very bottom of a PDF page, its y-coordinate may be calculated incorrectly, causing the GoTo action to jump to the wrong position or a blank area. Add page-break-after: avoid to your heading CSS to prevent headings from landing at page bottoms.

Culprit 4: The Editor Renders Pages as Images

Some editors use html2canvas under the hood, which rasterizes each page into a PNG and embeds the image in the PDF. No amount of link configuration will help here — the PDF contains images, not text or links. Check the PDF by selecting text: if you can't select individual words, your editor is rasterizing. Switch to an editor that uses vector-based PDF generation, or configure the library to skip the canvas step.

How Do You Verify Your Clickable TOC Actually Works?

Don't trust the preview. Don't trust the first page. Open the exported PDF in at least two different readers — Adobe Acrobat Reader and a browser-based viewer like PDF.js — and test every TOC link. Click "Section 1," confirm the jump. Click the last entry, confirm the jump. Click a deeply nested subheading (your #### level), confirm the jump.

Here's a concrete benchmark I use: for a 47-page document with 62 headings across four heading levels, a fully functional clickable TOC should let a reader reach any section in under 3 seconds — one click to jump, one scroll adjustment if the heading lands mid-page. If a reader has to scroll manually to find Section 4.2, your TOC is decoration, not navigation. And for technical documentation deliverables, decoration doesn't bill.

One last thing: if your editor's export pipeline simply cannot produce clickable TOCs after all configuration attempts, consider a hybrid workflow. Export your markdown to HTML, open it in a browser, and use Chrome's print-to-PDF with the "Save links to PDF" behavior enabled. It's not elegant, but it produces a clickable TOC in roughly 8 seconds for a 50-page document — and sometimes the pragmatic path is the one that ships.

Frequently Asked Questions

How do I create a clickable table of contents in a Markdown PDF?

To create a clickable table of contents, use standard Markdown heading syntax (like #, ##) and link them using anchor tags such as [Section Name](#section-name). Most browser-based Markdown editors will automatically convert these internal links into clickable bookmarks when exporting to PDF. Ensure your editor's PDF export settings have internal links or bookmarks enabled.

Why are my Markdown TOC links not working in the exported PDF?

If your table of contents links aren't clickable in the PDF, it usually means the editor's PDF export feature doesn't support anchor links or they are formatted incorrectly. Check your editor's documentation to ensure it supports internal link generation, and verify that your anchor IDs match the headings exactly without spaces. Some editors also require specific plugins or themes to enable this functionality.

Can I automatically generate a table of contents for Markdown to PDF conversion?

Yes, many browser-based Markdown editors support automatic TOC generation using syntax like [TOC] or by using specific extensions. When you use this feature, the editor scans your document for headings and creates a linked list automatically before exporting to PDF. This saves time and ensures your anchor links are perfectly formatted without manual entry.

How do I add PDF bookmarks from Markdown headings?

PDF bookmarks, which appear in the reader's sidebar navigation, are often generated automatically from your Markdown headings during the export process. If your browser-based Markdown editor uses a robust PDF engine like Puppeteer or wkhtmltopdf, it will map these heading levels directly to the PDF bookmark tree. Check your export settings to ensure the 'Include bookmarks' or 'Outline' option is checked.

Do all browser-based Markdown editors support clickable TOCs in PDFs?

No, not all browser-based editors support this feature natively because rendering internal anchor links into PDFs requires specific browser print-to-PDF configurations. You might need to use dedicated web editors like StackEdit or specialized Markdown-to-PDF web apps that explicitly mention PDF bookmark support. Always test the PDF export feature with a small document first to verify link interactivity.

How do I format anchor links for a Markdown table of contents?

To format anchor links correctly, type your heading normally (e.g., ## My Heading), then create a link using lowercase letters, replacing spaces with hyphens (e.g., [My Heading](#my-heading)). Punctuation should generally be removed, and numbers are usually kept. Following these rules ensures the browser correctly maps the TOC links to the corresponding headings during PDF export.

Is there a way to export Markdown to PDF with a sidebar TOC?

Exporting a Markdown file to a PDF with a sidebar table of contents depends on the PDF viewer's bookmark feature rather than the document itself. When you properly format your Markdown headings and use a compatible browser-based editor, the exported PDF will include an outline that appears as a sidebar in readers like Adobe Acrobat. Make sure your headings are hierarchical (H1, H2, H3) to create a nested, easy-to-navigate sidebar.

What is the best Markdown editor for creating PDFs with clickable tables of contents?

Editors like StackEdit, Dillinger, and specialized Markdown-to-PDF web apps are highly recommended for generating clickable TOCs. These platforms utilize advanced rendering engines that accurately translate Markdown anchor links and headings into interactive PDF elements. Look for web editors that explicitly highlight their PDF export capabilities and internal link support.

How to use HTML to force a clickable TOC in a Markdown PDF?

If native Markdown anchor links fail during PDF export, you can use standard HTML tags like <a href="#section-id">Section</a> and <h2 id="section-id">Section</h2> as a fallback. Most browser-based Markdown editors allow inline HTML, which gives you stricter control over the exact IDs used for linking. This method often forces the browser's print engine to retain the internal links when saving as a PDF.

Does CSS affect the clickable table of contents in a PDF export?

While CSS primarily controls the visual styling of your TOC, certain properties like page-break-after or display:none can affect how links are mapped across PDF pages. If your CSS hides the headings or alters their display properties, the browser might fail to generate the correct anchor points for the PDF. Keep your TOC and heading CSS straightforward to ensure maximum compatibility during PDF export.