How to Add PDF Bookmarks and Outline in Java
IronPDF's Java library lets you programmatically add bookmarks and outlines to PDF documents through the BookmarkManager class, supporting both single-layer and multi-layer bookmark structures with customizable navigation points.
Quickstart: Add PDF Bookmarks in Java
- Install IronPDF Java library and set your license key
- Load your PDF using
PdfDocument.fromFile() - Get the
BookmarkManagerwithpdf.getBookmark() - Add bookmarks using
addBookMarkAtEnd("Title", pageNumber) - Save the PDF with
pdf.saveAs()
```java :title=Quickstart //:path=/static-assets/ironpdf-java/content-code-examples/how-to/bookmarks/quickstart.java PdfDocument pdf = PdfDocument.fromFile(Path.of("document.pdf")); BookmarkManager bookmarks = pdf.getBookmark(); bookmarks.addBookMarkAtEnd("Chapter 1", 0); pdf.saveAs(Path.of("bookmarked.pdf"));
PDF bookmarks improve the usability and navigation of your documents. Outlines provide structured navigation within PDFs, letting users jump directly to key sections, much like a table of contents. This proves essential when working with lengthy documents, reports, or multi-chapter PDFs that require organized navigation.
IronPDF simplifies PDF manipulation in Java applications. The bookmarking API gives you straightforward methods for creating custom bookmarks in PDF files. The library integrates with Java applications and supports various PDF manipulation features beyond bookmarking, including [merging PDFs](https://ironpdf.com/java/how-to/java-merge-pdf-tutorial/), [creating forms](https://ironpdf.com/java/how-to/create-forms/), and [adding watermarks](https://ironpdf.com/java/how-to/custom-watermark/).
<div class="hsg-featured-snippet">
<h2>How to Add PDF Bookmarks and Outline</h2>
<ol>
<li><a href="https://ironpdf.com/java/#download-modal">Install the Java library to add bookmarks to PDFs</a></li>
<li>Use the <strong>PdfDocument</strong> class to load an existing PDF file in Java</li>
<li>Create and customize bookmarks with the <strong>BookmarkManager</strong> class</li>
<li>Use <code>addBookMarkAtEnd</code> to add bookmarks to specific pages of the PDF</li>
<li>Save the PDF document containing the new outline and bookmarks</li>
</ol>
</div>
## What Do I Need Before Getting Started?
Before implementing PDF bookmarks, confirm that IronPDF is configured in your Java project. The library requires Java 8 or higher and integrates through [Maven or Gradle](https://central.sonatype.com/artifact/com.ironsoftware/ironpdf). Add the IronPDF dependency to your project's build file. For detailed setup instructions, refer to the [Get Started Overview](https://ironpdf.com/java/docs/).
A valid license key is required for development and production use. Set the license key at the start of your application before calling any IronPDF methods. For information about licensing options, visit the [licensing guide](https://ironpdf.com/java/get-started/license-keys/).
TipsAll page indexes in IronPDF use zero-based numbering. Page 1 of your document is index 0, page 2 is index 1, and so on.
## How Do I Add Outline and Bookmarks to a PDF?
The examples below use this [sample PDF](/static-assets/ironpdf-java/howto/bookmarks/NovelSample.pdf) to demonstrate outline and bookmark creation. The process involves loading an existing PDF document and using IronPDF's `BookmarkManager` to add navigation points throughout the document.
### How Can I Add a Single Layer of Bookmarks?
A flat bookmark list suits documents with a clear, non-hierarchical structure: reports, product manuals, or slide decks where each section stands on its own. After loading the PDF from a file path using `PdfDocument.fromFile()`, retrieve the `BookmarkManager` object to start adding bookmarks.
The `addBookMarkAtEnd` and `addBookMarkAtStart` methods add entries to the end or start of the bookmark collection respectively. These methods give you flexibility in organizing bookmarks to match your document's structure. Each entry takes a display title and a zero-based page index.
```java
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/bookmarks/single-layer.java
import java.io.IOException;
import java.nio.file.Path;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
import com.ironsoftware.ironpdf.bookmark.BookmarkManager;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key for IronPDF
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load the PDF file
PdfDocument pdf = PdfDocument.fromFile(Path.of("NovelSample.pdf"));
// Get BookmarkManager object to manage bookmarks
BookmarkManager bookmarks = pdf.getBookmark();
// Add bookmarks at the end of the bookmark collection
bookmarks.addBookMarkAtEnd("Title Page", 0);
bookmarks.addBookMarkAtEnd("Table of Contents", 1);
bookmarks.addBookMarkAtEnd("Dedication Page", 2);
bookmarks.addBookMarkAtEnd("First Page", 3);
bookmarks.addBookMarkAtStart("Page 4", 6);
// Save the modified PDF with bookmarks
pdf.saveAs(Path.of("bookmarked.pdf"));
}
}
With the PDF viewer above, check the table of contents in the top-left corner of most browsers to see all added bookmarks. This flat bookmark structure provides straightforward navigation for documents with simple organizational needs.
How Do I Create Multiple Layers of Bookmarks?
Nested bookmarks are the right choice for technical documentation, research reports, or any multi-chapter document where readers need to navigate not just to chapters, but to subsections within those chapters. Start with the same flat bookmarks created in the previous section, then use insertBookmark to add entries on new layers.
The insertBookmark method accepts four parameters: the bookmark name, the target page index, the parent bookmark name, and the preceding sibling bookmark name. Passing a parent bookmark name creates a child entry nested beneath it. Setting the sibling parameter to null places the new entry as the first child of that parent.
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/bookmarks/multi-layer.java
import java.io.IOException;
import java.nio.file.Path;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
import com.ironsoftware.ironpdf.bookmark.BookmarkManager;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load the PDF file
PdfDocument pdf = PdfDocument.fromFile(Path.of("NovelSample.pdf"));
// Get BookmarkManager object
BookmarkManager bookmarks = pdf.getBookmark();
// Add top-level bookmarks at the end
bookmarks.addBookMarkAtEnd("Title Page", 0);
bookmarks.addBookMarkAtEnd("Table of Contents", 1);
bookmarks.addBookMarkAtEnd("Dedication", 2);
// Insert second-layer bookmarks as children of existing entries
bookmarks.insertBookmark("First Page", 3, "Table of Contents", null);
bookmarks.insertBookmark("Second Page", 4, "Table of Contents", "First Page");
bookmarks.insertBookmark("End of Sample", 7, "Title Page", null);
bookmarks.insertBookmark("Fourth page", 6, "Table of Contents", "Second Page");
// Save the modified PDF with nested bookmarks
pdf.saveAs(Path.of("multiLayer.pdf"));
}
}
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/bookmarks/multi-layer.java
import java.io.IOException;
import java.nio.file.Path;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
import com.ironsoftware.ironpdf.bookmark.BookmarkManager;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load the PDF file
PdfDocument pdf = PdfDocument.fromFile(Path.of("NovelSample.pdf"));
// Get BookmarkManager object
BookmarkManager bookmarks = pdf.getBookmark();
// Add top-level bookmarks at the end
bookmarks.addBookMarkAtEnd("Title Page", 0);
bookmarks.addBookMarkAtEnd("Table of Contents", 1);
bookmarks.addBookMarkAtEnd("Dedication", 2);
// Insert second-layer bookmarks as children of existing entries
bookmarks.insertBookmark("First Page", 3, "Table of Contents", null);
bookmarks.insertBookmark("Second Page", 4, "Table of Contents", "First Page");
bookmarks.insertBookmark("End of Sample", 7, "Title Page", null);
bookmarks.insertBookmark("Fourth page", 6, "Table of Contents", "Second Page");
// Save the modified PDF with nested bookmarks
pdf.saveAs(Path.of("multiLayer.pdf"));
}
}
The PDF above shows the tree structure of bookmarks created by insertBookmark. Expand the outline panel to verify how each child entry nests beneath its parent. This layered approach suits reports with chapters, sub-chapters, and appendices.
How Do I Retrieve Existing Bookmarks from a PDF?
Reading bookmark data from a PDF is a prerequisite when updating documents without rebuilding the entire navigation structure. IronPDF makes this accessible through the same BookmarkManager interface used to add bookmarks. Load the PDF with PdfDocument.fromFile(), access the BookmarkManager, then call getBookmarks() to retrieve all top-level bookmarks.
Use get(index) to access a specific bookmark by its position in the list. The getText() method returns the bookmark's display label, while getPageIndex() returns the zero-based page number it targets. Child bookmarks are not included in the flat list returned by getBookmarks(); access them through each parent bookmark's getChildren() method.
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/bookmarks/retrieve-bookmarks.java
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
import com.ironsoftware.ironpdf.bookmark.Bookmark;
import com.ironsoftware.ironpdf.bookmark.BookmarkManager;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load the PDF file with bookmarks
PdfDocument pdf = PdfDocument.fromFile(Path.of("bookmarked.pdf"));
// Retrieve the bookmark manager
BookmarkManager bookmarks = pdf.getBookmark();
// Retrieve list of all bookmarks (includes child bookmarks)
List<Bookmark> bookmarkList = bookmarks.getBookmarks();
// Access a specific bookmark by zero-based index
Bookmark bookmark = bookmarkList.get(2);
// Print bookmark details
System.out.println("Bookmark Title: " + bookmark.getText());
System.out.println("Page Number: " + bookmark.getPageIndex());
// Check if bookmark has children
if (bookmark.getChildren() != null && !bookmark.getChildren().isEmpty()) {
System.out.println("Number of child bookmarks: " + bookmark.getChildren().size());
}
}
}
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/bookmarks/retrieve-bookmarks.java
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
import com.ironsoftware.ironpdf.bookmark.Bookmark;
import com.ironsoftware.ironpdf.bookmark.BookmarkManager;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load the PDF file with bookmarks
PdfDocument pdf = PdfDocument.fromFile(Path.of("bookmarked.pdf"));
// Retrieve the bookmark manager
BookmarkManager bookmarks = pdf.getBookmark();
// Retrieve list of all bookmarks (includes child bookmarks)
List<Bookmark> bookmarkList = bookmarks.getBookmarks();
// Access a specific bookmark by zero-based index
Bookmark bookmark = bookmarkList.get(2);
// Print bookmark details
System.out.println("Bookmark Title: " + bookmark.getText());
System.out.println("Page Number: " + bookmark.getPageIndex());
// Check if bookmark has children
if (bookmark.getChildren() != null && !bookmark.getChildren().isEmpty()) {
System.out.println("Number of child bookmarks: " + bookmark.getChildren().size());
}
}
}
getBookmarks() method returns a flat list of top-level bookmarks only. To traverse the full bookmark tree, recursively call getChildren() on each bookmark that has nested entries.This retrieval pattern is useful when auditing an existing PDF's navigation structure before distribution, or when building tooling that needs to validate that required sections are correctly bookmarked before publication.
How Can I Insert a Bookmark at a Specific Index?
Inserting bookmarks at a specific position lets you update existing PDFs incrementally, adding new sections without rebuilding the full outline from scratch. This is particularly useful when PDFs are generated or modified in a pipeline and new content is appended downstream.
Retrieve the flat bookmark list using getBookmarks(), select the target bookmark by its list index, then call addNextBookmark to insert a new sibling immediately after it. Use addChildBookmark to place a new entry one level deeper, nested under the selected bookmark. Both methods accept a title string and a zero-based page index.
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/bookmarks/insert-at-index.java
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
import com.ironsoftware.ironpdf.bookmark.Bookmark;
import com.ironsoftware.ironpdf.bookmark.BookmarkManager;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load the PDF modified in the multi-layer example
PdfDocument pdf = PdfDocument.fromFile(Path.of("multiLayer.pdf"));
// Get the BookmarkManager
BookmarkManager bookmarks = pdf.getBookmark();
// Retrieve the flat bookmark list
List<Bookmark> bookmarkList = bookmarks.getBookmarks();
// Select a bookmark at a specific index
Bookmark bookmark = bookmarkList.get(5);
// Insert a new bookmark after the selected entry
bookmark.addNextBookmark("Fourth Page", 6);
// Add a child bookmark under the selected entry
bookmark.addChildBookmark("Section 1", 7);
// Save the updated PDF
pdf.saveAs(Path.of("specificIndex.pdf"));
}
}
//:path=/static-assets/ironpdf-java/content-code-examples/how-to/bookmarks/insert-at-index.java
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import com.ironsoftware.ironpdf.License;
import com.ironsoftware.ironpdf.PdfDocument;
import com.ironsoftware.ironpdf.bookmark.Bookmark;
import com.ironsoftware.ironpdf.bookmark.BookmarkManager;
public class Main {
public static void main(String[] args) throws IOException {
// Set the license key
License.setLicenseKey("IRONPDF-MYLICENSE-KEY-1EF01");
// Load the PDF modified in the multi-layer example
PdfDocument pdf = PdfDocument.fromFile(Path.of("multiLayer.pdf"));
// Get the BookmarkManager
BookmarkManager bookmarks = pdf.getBookmark();
// Retrieve the flat bookmark list
List<Bookmark> bookmarkList = bookmarks.getBookmarks();
// Select a bookmark at a specific index
Bookmark bookmark = bookmarkList.get(5);
// Insert a new bookmark after the selected entry
bookmark.addNextBookmark("Fourth Page", 6);
// Add a child bookmark under the selected entry
bookmark.addChildBookmark("Section 1", 7);
// Save the updated PDF
pdf.saveAs(Path.of("specificIndex.pdf"));
}
}
The addNextBookmark method inserts the new entry as a sibling of the selected bookmark, immediately after it in the list. The addChildBookmark method places the new entry one level deeper, nested under the selected bookmark. Both methods accept a title string and a zero-based page index.
What Are the Next Steps for PDF Bookmarks in Java?
PDF bookmarks give users a direct navigation path through complex documents without scrolling. IronPDF's BookmarkManager handles the full range of bookmark operations: adding flat entry lists, building deep multi-level outlines, retrieving existing entries, and inserting at specific positions.
To continue working with document structure and navigation features, explore these related resources:
- Split PDFs in Java: create smaller, self-contained documents that each carry their own bookmark structure
- Print PDFs in Java: send bookmarked documents to a printer with navigation preserved
- Java PDF tutorials: additional end-to-end examples for common PDF workflows
- Add annotations to PDFs in Java: attach comments and markup to specific page locations
- IronPDF for Java examples: copy-paste code samples for the full IronPDF Java API
Start your free trial to add bookmarks, outlines, and other navigation features to your Java PDF workflow. To purchase a license for production use, view licensing options.
Frequently Asked Questions
How do I add bookmarks to a PDF document in Java?
Load your PDF using PdfDocument.fromFile(), then call pdf.getBookmark() to get the BookmarkManager. Use addBookMarkAtEnd("Title", pageIndex) to add each bookmark by display name and zero-based page number, then save with pdf.saveAs().
What are the prerequisites for adding PDF bookmarks in Java?
You need Java 8 or higher, the IronPDF library added as a Maven or Gradle dependency, and a valid license key set with License.setLicenseKey() before any IronPDF calls. No additional tools or frameworks are required.
Can I create multi-level bookmark hierarchies in PDFs?
Yes. Add top-level bookmarks first with addBookMarkAtEnd, then call insertBookmark(name, pageIndex, parentName, siblingName) to nest child entries beneath a parent bookmark. Pass null as the sibling name to place the new entry as the first child.
What is the difference between addBookMarkAtEnd and insertBookmark?
addBookMarkAtEnd appends a new top-level entry to the end of the bookmark list. insertBookmark places a bookmark at a specific position in the hierarchy by specifying a parent bookmark name and an optional preceding sibling, enabling nested outlines.
How do I read existing bookmarks from a PDF in Java?
Call pdf.getBookmark().getBookmarks() to retrieve a flat list of top-level bookmarks. Access individual entries by index using list.get(index). Use bookmark.getText() for the title and bookmark.getPageIndex() for the zero-based page number. Child bookmarks are accessible via bookmark.getChildren().
How do I insert a bookmark after a specific existing bookmark?
Retrieve the bookmark list with getBookmarks(), select the target entry by index, then call bookmark.addNextBookmark("Title", pageIndex) to insert a sibling immediately after it, or bookmark.addChildBookmark("Title", pageIndex) to nest a new entry beneath it.


