Long documents need navigation. A table of contents with clickable links lets readers jump directly to sections. Here's how to generate one automatically from your HTML headings.
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new [ChromePdfRenderer](https://ironpdf.com/blog/videos/how-to-render-html-string-to-pdf-in-csharp-ironpdf/)();
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.WithLinks;
var html = @"
<h1>Introduction</h1>
<p>Opening content...</p>
<h2>Background</h2>
<p>More content...</p>
<h1>Main Topic</h1>
<p>Details here...</p>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("document-with-toc.pdf");
IronPDF scans your HTML for heading tags (h1-h6) and generates a linked table of contents automatically.
How Does Automatic TOC Generation Work?
When you enable TableOfContents:
- IronPDF parses your HTML for
<h1>through<h6>tags - Extracts heading text and determines hierarchy
- Generates a TOC page with clickable hyperlinks
- Links jump directly to each heading in the PDF
The TOC appears at the beginning by default, or you can control placement with a placeholder div.
What Are the TOC Options?
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
// With hyperlinks (recommended)
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.WithLinks;
// Plain text only (no navigation)
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.TextOnly;
// Disabled (default)
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.None;
Use WithLinks for interactive PDFs. TextOnly for print-focused documents where links don't matter.
How Do I Control TOC Placement?
By default, TOC goes at the start. Place it elsewhere with a div:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.WithLinks;
var html = @"
<html>
<body>
<h1>Title Page</h1>
<p>Welcome to this document.</p>
<!-- TOC will be inserted here -->
<div id='ironpdf-toc'></div>
<h1>Chapter 1</h1>
<p>First chapter content...</p>
<h1>Chapter 2</h1>
<p>Second chapter content...</p>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
The id='ironpdf-toc' div marks where the TOC should appear.
How Do I Style the Table of Contents?
Custom CSS for TOC appearance:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.WithLinks;
var html = @"
<html>
<head>
<style>
/* TOC container */
.ironpdf-toc {
padding: 20px;
margin: 20px 0;
}
/* TOC title */
.ironpdf-toc-title {
font-size: 24px;
font-weight: bold;
margin-bottom: 15px;
color: #333;
}
/* TOC entries */
.ironpdf-toc-item {
margin: 8px 0;
}
/* Indentation for nested headings */
.ironpdf-toc-item-h1 { margin-left: 0; font-weight: bold; }
.ironpdf-toc-item-h2 { margin-left: 20px; }
.ironpdf-toc-item-h3 { margin-left: 40px; }
.ironpdf-toc-item-h4 { margin-left: 60px; }
/* Links */
.ironpdf-toc-item a {
color: #007bff;
text-decoration: none;
}
.ironpdf-toc-item a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div id='ironpdf-toc'></div>
<h1>Introduction</h1>
<h2>Purpose</h2>
<h2>Scope</h2>
<h1>Details</h1>
<h2>Implementation</h2>
<h3>Step 1</h3>
<h3>Step 2</h3>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
CSS selectors target TOC elements for full styling control.
How Do I Add Bookmarks Manually?
For existing PDFs or custom navigation:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var pdf = PdfDocument.FromFile("report.pdf");
// Add top-level bookmarks
pdf.Bookmarks.AddBookMarkAtEnd("Executive Summary", 0);
pdf.Bookmarks.AddBookMarkAtEnd("Introduction", 2);
pdf.Bookmarks.AddBookMarkAtEnd("Analysis", 5);
pdf.Bookmarks.AddBookMarkAtEnd("Conclusions", 15);
pdf.Bookmarks.AddBookMarkAtEnd("References", 18);
pdf.SaveAs("bookmarked-report.pdf");
Bookmarks appear in the PDF reader's sidebar for navigation. Page numbers are zero-indexed.
How Do I Create Nested Bookmarks?
Hierarchical structure for complex documents:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var pdf = PdfDocument.FromFile("manual.pdf");
// Top-level sections
var chapter1 = pdf.Bookmarks.AddBookMarkAtEnd("Chapter 1: Getting Started", 0);
var chapter2 = pdf.Bookmarks.AddBookMarkAtEnd("Chapter 2: Advanced Topics", 10);
var chapter3 = pdf.Bookmarks.AddBookMarkAtEnd("Chapter 3: Reference", 25);
// Nested under Chapter 1
chapter1.Children.AddBookMarkAtEnd("1.1 Installation", 1);
chapter1.Children.AddBookMarkAtEnd("1.2 Configuration", 3);
chapter1.Children.AddBookMarkAtEnd("1.3 First Steps", 6);
// Nested under Chapter 2
chapter2.Children.AddBookMarkAtEnd("2.1 Performance", 11);
chapter2.Children.AddBookMarkAtEnd("2.2 Security", 15);
var section23 = chapter2.Children.AddBookMarkAtEnd("2.3 Integration", 18);
// Third level nesting
section23.Children.AddBookMarkAtEnd("2.3.1 API Setup", 19);
section23.Children.AddBookMarkAtEnd("2.3.2 Authentication", 21);
pdf.SaveAs("nested-bookmarks.pdf");
Nested bookmarks create a tree structure in the PDF reader's navigation panel.
How Do I Read Existing Bookmarks?
Inspect and manipulate existing bookmarks:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var pdf = PdfDocument.FromFile("existing-document.pdf");
// Get all bookmarks
var bookmarks = pdf.Bookmarks.GetAllBookmarks();
foreach (var bookmark in bookmarks)
{
Console.WriteLine($"Title: {bookmark.Title}, Page: {bookmark.PageIndex}");
// Check for children
foreach (var child in bookmark.Children)
{
Console.WriteLine($" - {child.Title}, Page: {child.PageIndex}");
}
}
Useful for auditing documents or building custom navigation interfaces.
How Do I Generate TOC for Merged Documents?
Important: Merge before adding TOC, not after:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
// Merge documents first
var part1 = PdfDocument.FromFile("chapter1.pdf");
var part2 = PdfDocument.FromFile("chapter2.pdf");
var merged = PdfDocument.Merge(part1, part2);
// Then add bookmarks manually
merged.Bookmarks.AddBookMarkAtEnd("Chapter 1", 0);
merged.Bookmarks.AddBookMarkAtEnd("Chapter 2", part1.PageCount);
merged.SaveAs("complete-book.pdf");
// Note: Automatic TOC won't work after merge
// because heading tags are lost in the PDF
For HTML-based TOC, generate from a single HTML document, not merged PDFs.
How Do I Create a TOC with Page Numbers?
Include page numbers in the TOC:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.WithLinks;
var html = @"
<html>
<head>
<style>
.ironpdf-toc-item {
display: flex;
justify-content: space-between;
}
.ironpdf-toc-item-text {
flex: 1;
}
.ironpdf-toc-item-page {
margin-left: 10px;
}
/* Dotted leader line */
.ironpdf-toc-item::after {
content: '';
flex: 1;
border-bottom: 1px dotted #999;
margin: 0 10px;
}
</style>
</head>
<body>
<div id='ironpdf-toc'></div>
<h1>Section 1</h1>
<p>Content...</p>
<h1>Section 2</h1>
<p>More content...</p>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
CSS styling creates the classic dotted-line leader between title and page number.
How Do I Handle Long Documents?
For documents with many sections:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.WithLinks;
// Only include h1 and h2 in TOC to keep it manageable
var html = @"
<html>
<head>
<style>
/* Hide h3+ from TOC */
.ironpdf-toc-item-h3,
.ironpdf-toc-item-h4,
.ironpdf-toc-item-h5,
.ironpdf-toc-item-h6 {
display: none;
}
</style>
</head>
<body>
<div id='ironpdf-toc'></div>
<h1>Part 1</h1>
<h2>Chapter 1</h2>
<h3>Section 1.1</h3> <!-- Hidden from TOC -->
<h3>Section 1.2</h3> <!-- Hidden from TOC -->
<h2>Chapter 2</h2>
</body>
</html>";
var pdf = renderer.RenderHtmlAsPdf(html);
Limit TOC depth to keep navigation manageable.
How Do I Add Page Numbers to Headers?
Match TOC entries with visible page numbers:
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TableOfContents = TableOfContentsTypes.WithLinks;
// Add page numbers in footer
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = @"
<div style='text-align:center; font-size:10px;'>
Page {page}
</div>"
};
var pdf = renderer.RenderHtmlAsPdf(documentHtml);
Page numbers in footers help readers locate sections referenced in the TOC.
Quick Reference
| Task | Approach |
|---|---|
| Auto TOC | TableOfContents = TableOfContentsTypes.WithLinks |
| Place TOC | <div id='ironpdf-toc'></div> |
| Style TOC | Target .ironpdf-toc-* CSS classes |
| Add bookmark | pdf.Bookmarks.AddBookMarkAtEnd("Title", pageIndex) |
| Nest bookmarks | parent.Children.AddBookMarkAtEnd(...) |
| Read bookmarks | pdf.Bookmarks.GetAllBookmarks() |
A good table of contents transforms a long PDF from a wall of text into a navigable document. Let readers jump straight to what they need.
For more navigation options, see the IronPDF table of contents documentation.
Written by Jacob Mellor, CTO at Iron Software. Jacob created IronPDF and leads a team of 50+ engineers building .NET document processing libraries.
Top comments (0)