Adding, Editing, or Deleting PDF Bookmarks in React with JavaScript

Bookmarks in PDF documents are essential tools for navigating document content, especially for long documents where bookmarks help readers quickly locate target sections. With Spire.PDF for JavaScript's bookmark management capabilities, you can directly add multi-level bookmarks, modify existing bookmark titles and styles, or delete unwanted bookmarks in React applications, all completed in the browser via WebAssembly without relying on backend services.

Spire.PDF for JavaScript processes PDF documents directly in the browser based on WebAssembly, managing input and output files through a virtual file system (VFS).

This article covers three core features:

For installation and project configuration, refer to Integrating Spire.PDF for JavaScript in a React Project. The following examples assume Spire.PDF is installed and the WebAssembly module has been initialized.


Adding PDF Bookmarks

Spire.PDF for JavaScript allows you to batch add multi-level bookmarks to existing PDF documents. By iterating through the PdfDocument.Pages collection, you can create parent and child bookmarks for each page, use PdfDestination to specify the jump target page and position, and add child bookmarks via PdfBookmarkCollection.Add to form a hierarchical structure.

function App() {
  const addPdfBookmarks = async () => {
    // Get the Spire.PDF WASM module
    const pdfModule = window.wasmModule?.spirepdf;

    // Check if the module is ready
    if (!pdfModule) {
      alert('Spire.PDF is not ready yet');
      return;
    }

    // Load the PDF file to be processed into VFS
    const inputFileName = 'Sample.pdf';
    await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);

    // Create a PdfDocument object and load the PDF document
    let doc = new pdfModule.PdfDocument();
    doc.LoadFromFile(inputFileName);

    // Iterate through each page of the PDF, adding parent and child bookmarks for each page
    for (let i = 0; i < doc.Pages.Count; i++) {
      let page = doc.Pages.get_Item(i);

      // Set the parent bookmark title and target position
      let bookmarkTitle = "Bookmark-" + (i + 1);
      let bookmarkDest = new pdfModule.PdfDestination({ page: page, location: new pdfModule.PointF(0, 0) });

      // Create and configure the parent bookmark
      let bookmark = doc.Bookmarks.Add(bookmarkTitle);
      bookmark.Color = new pdfModule.PdfRGBColor({ color: pdfModule.Color.get_SaddleBrown() });
      bookmark.DisplayStyle = pdfModule.PdfTextStyle.Bold;
      bookmark.Action = new pdfModule.PdfGoToAction({ destination: bookmarkDest });

      // Set the child bookmark title and target position
      let childBookmarkTitle = "Sub-Bookmark-" + (i + 1);
      let childBookmarkDest = new pdfModule.PdfDestination({ page: page, location: new pdfModule.PointF(0, 100) });

      // Create child bookmark via PdfBookmarkCollection.Add of the parent bookmark
      let childBookmark = bookmark.Add(childBookmarkTitle);
      childBookmark.Color = new pdfModule.PdfRGBColor({ color: pdfModule.Color.get_Coral() });
      childBookmark.DisplayStyle = pdfModule.PdfTextStyle.Italic;
      childBookmark.Action = new pdfModule.PdfGoToAction({ destination: childBookmarkDest });
    }

    // Save the document and trigger download
    const outputFileName = "AddBookmark.pdf";
    doc.SaveToFile(outputFileName);
    doc.Close();

    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: "application/pdf" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Add PDF Bookmarks</h1>
      <button onClick={addPdfBookmarks}>
        Start Adding
      </button>
    </div>
  );
}

export default App;

Document after batch adding multi-level bookmarks by iterating through PDF pages

Document after batch adding multi-level bookmarks by iterating through PDF pages


Editing PDF Bookmarks

For existing PDF documents, you can load them and edit the bookmarks within. Use PdfDocument.Bookmarks.get_Item to retrieve a bookmark node at a specified index, then modify its Title, Color, and DisplayStyle properties. Bookmarks support hierarchical structure, and you can recursively traverse and edit all child bookmark nodes.

function App() {
  const editPdfBookmarks = async () => {
    // Get the Spire.PDF WASM module
    const pdfModule = window.wasmModule?.spirepdf;

    // Check if the module is ready
    if (!pdfModule) {
      alert('Spire.PDF is not ready yet');
      return;
    }

    // Load the PDF file to be processed into VFS
    const inputFileName = 'AddBookmark.pdf';
    await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);

    // Create a PdfDocument object and load the PDF document
    let doc = new pdfModule.PdfDocument();
    doc.LoadFromFile(inputFileName);

    // Function to recursively edit child bookmarks
    function editChildBookmarks(parentBookmark) {
      for (let i = 0; i < parentBookmark.Count; i++) {
        let childBookmark = parentBookmark.get_Item(i);
        childBookmark.Color = new pdfModule.PdfRGBColor({ color: pdfModule.Color.get_Blue() });
        childBookmark.DisplayStyle = pdfModule.PdfTextStyle.Regular;
        editChildBookmarks(childBookmark);
      }
    }

    // Get the first bookmark and modify its properties
    let bookmark = doc.Bookmarks.get_Item(0);
    bookmark.Title = "Modified Bookmark";
    bookmark.Color = new pdfModule.PdfRGBColor({ color: pdfModule.Color.get_Black() });
    bookmark.DisplayStyle = pdfModule.PdfTextStyle.Bold;

    // Recursively edit all child bookmarks
    editChildBookmarks(bookmark);

    // Save the document and trigger download
    const outputFileName = "EditBookmark.pdf";
    doc.SaveToFile(outputFileName);
    doc.Close();

    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: "application/pdf" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Edit PDF Bookmarks</h1>
      <button onClick={editPdfBookmarks}>
        Start Editing
      </button>
    </div>
  );
}

export default App;

Document effect after editing PDF bookmarks

Document effect after editing PDF bookmarks


Deleting PDF Bookmarks

To remove unwanted bookmarks from a PDF document, you can use the PdfDocument.Bookmarks.RemoveAt method to remove a specified bookmark by index. If you need to delete all bookmarks, you can iterate through the collection and delete them one by one, or use RemoveAt(0) in a loop until the collection is empty.

function App() {
  const deletePdfBookmarks = async () => {
    // Get the Spire.PDF WASM module
    const pdfModule = window.wasmModule?.spirepdf;

    // Check if the module is ready
    if (!pdfModule) {
      alert('Spire.PDF is not ready yet');
      return;
    }

    // Load the PDF file to be processed into VFS
    const inputFileName = 'AddBookmark.pdf';
    await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);

    // Create a PdfDocument object and load the PDF document
    let doc = new pdfModule.PdfDocument();
    doc.LoadFromFile(inputFileName);

    // Delete the first bookmark
    doc.Bookmarks.RemoveAt(0);

    // Save the document and trigger download
    const outputFileName = "DeleteBookmark.pdf";
    doc.SaveToFile(outputFileName);
    doc.Close();

    const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
    const blob = new Blob([fileArray], { type: "application/pdf" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = outputFileName;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div style={{ textAlign: 'center', height: '300px' }}>
      <h1>Delete PDF Bookmarks</h1>
      <button onClick={deletePdfBookmarks}>
        Start Deleting
      </button>
    </div>
  );
}

export default App;

Document after deleting specified PDF bookmarks

Document after deleting specified PDF bookmarks


Frequently Asked Questions

How to Add Multi-Level Nested Bookmarks

Reason: PDF bookmarks support hierarchical structure, allowing you to create parent and child bookmarks for document navigation.

Solution: You can add child bookmarks through the parent bookmark's Add method to form a nested structure. The following code demonstrates how to create two-level bookmarks:

// Create a parent bookmark
let parentBookmark = doc.Bookmarks.Add("Chapter 1");
parentBookmark.DisplayStyle = pdfModule.PdfTextStyle.Bold;

// Add a child bookmark via the parent bookmark's Add method
let childBookmark = parentBookmark.Add("1.1 Section");
childBookmark.DisplayStyle = pdfModule.PdfTextStyle.Regular;

What Properties Can Be Modified When Editing Bookmarks

Reason: Spire.PDF for JavaScript provides rich bookmark property settings for customizing bookmark appearance.

Solution: The following properties can be modified:

  • Title: Bookmark title text
  • Color: Bookmark color, set using PdfRGBColor
  • DisplayStyle: Display style, options include Bold (bold), Italic (italic), Underline (underline), Regular (normal)
  • Action: Bookmark jump action, set using PdfGoToAction
let bookmark = doc.Bookmarks.get_Item(0);
bookmark.Title = "New Title";
bookmark.Color = new pdfModule.PdfRGBColor({ color: pdfModule.Color.get_Blue() });
bookmark.DisplayStyle = pdfModule.PdfTextStyle.Bold | pdfModule.PdfTextStyle.Italic;

How to Delete All Bookmarks from a PDF

Reason: Sometimes you need to clear all bookmarks from a document, such as when regenerating or removing sensitive navigation information.

Solution: You can delete them one by one by repeatedly calling RemoveAt(0), since after each deletion, the bookmarks at index 0 are removed and subsequent bookmarks automatically shift forward:

while (doc.Bookmarks.Count > 0) {
  doc.Bookmarks.RemoveAt(0);
}

Get a Free License

If you wish to remove the evaluation message from the result document or remove feature limitations, please contact sales to obtain a temporary license valid for 30 days.