How to use PDF.js to highlight text programmatically

Table of contents

    In this tutorial, you’ll learn two ways to work with highlight annotations in PDFs. First, you’ll integrate PDF.js to render existing highlights (and optionally simulate new ones with HTML overlays). Then, you’ll use Nutrient Web SDK to programmatically create and embed true highlight annotations into a PDF itself.
    How to use PDF.js to highlight text programmatically
    TL;DR
    • PDF.js (free viewer) can simulate highlights with HTML overlays but cannot embed or save them in the PDF. It’s great for quick, lightweight visuals.
    • Nutrient Web SDK (commercial) offers a full annotation API that writes real highlight objects into a file, with precise positioning, flattening, and other advanced features. Use it when you need persistent, production‑grade PDF annotations.

    PDF.js is primarily designed as a PDF viewer, and its manipulation capabilities may be limited compared to those of dedicated PDF editing software.

    Downloading the PDF.js library

    To get started with PDF.js, download(opens in a new tab) the library as a ZIP file, or clone the repository using Git.

    Extract the ZIP file and copy the pdf.mjs and pdf.worker.mjs files from the build/ folder to your project directory.

    In your HTML file, add the following script tag to load the PDF.js library:

    <!DOCTYPE html>
    <html>
    <head>
    <script src="./pdf.mjs"></script>
    </head>
    <!-- Rest of your HTML code -->
    </html>

    Loading and rendering PDF documents

    To get started, you need to load the PDF document and render it in a specified container. For this tutorial, you’ll use a canvas element to display the PDF page.

    Make sure you replace annotation.pdf with the actual URL or path to your PDF document. You can use this demo document as an example:

    <body>
    <!-- Canvas to place the PDF -->
    <canvas id="canvas"></canvas>
    <script>
    // Get the canvas element.
    const canvas = document.getElementById("canvas");
    // Get the PDF file URL.
    const pdfUrl = "annotation.pdf"; // Replace with the URL of your PDF document
    // Configure the PDF.js worker source.
    pdfjsLib.GlobalWorkerOptions.workerSrc = "./pdf.worker.mjs";
    // Load the PDF file using PDF.js.
    pdfjsLib.getDocument(pdfUrl).promise.then(function (pdfDoc) {
    // Get the first page of the PDF file.
    pdfDoc.getPage(1).then(function (page) {
    const viewport = page.getViewport({ scale: 1 });
    // Set the canvas dimensions to match the PDF page size.
    canvas.width = viewport.width;
    canvas.height = viewport.height;
    // Set the canvas rendering context.
    const ctx = canvas.getContext("2d");
    const renderContext = {
    canvasContext: ctx,
    viewport: viewport,
    };
    // Render the PDF page to the canvas.
    page.render(renderContext).promise.then(function () {
    console.log("Rendering complete");
    // Call the function to render highlight annotations after the PDF page is rendered.
    renderHighlightAnnotations(page);
    });
    });
    });
    </script>
    </body>

    Adding highlight annotations programmatically

    Use the getAnnotations() method to retrieve existing annotations from the PDF page. For this tutorial, you’ll focus on highlight annotations specifically:

    function renderHighlightAnnotations(page) {
    page.getAnnotations().then(function (annotations) {
    annotations.forEach(function (annotation) {
    if (annotation.subtype === "Highlight") {
    const highlightRect = annotation.rect;
    const highlight = document.createElement("div");
    highlight.style.position = "absolute";
    highlight.style.left = highlightRect[0] + "px";
    highlight.style.top = highlightRect[1] + "px";
    highlight.style.width = highlightRect[2] - highlightRect[0] + "px";
    highlight.style.height = highlightRect[3] - highlightRect[1] + "px";
    highlight.style.backgroundColor = "yellow";
    highlight.style.opacity = "0.5";
    document.body.appendChild(highlight);
    }
    });
    });
    }

    The renderHighlightAnnotations(page) function retrieves all annotations from the specified page. If the annotation’s subtype matches 'Highlight', it creates a yellow rectangle (highlight) using a div element positioned and sized according to the annotation’s rectangle coordinates. The highlight is then added to the document body.

    After executing these steps, the highlight annotations present in the PDF document will be displayed as yellow rectangles with 50 percent opacity on top of the PDF pages.

    Nutrient Web SDK

    We at Nutrient work on the next generation of PDF viewers for the web. We offer a commercial JavaScript PDF viewer library that can easily be integrated into your web application. Nutrient Web SDK offers 30+ features, enabling users to view, annotate, edit, and sign PDFs directly within the browser.

    Requirements

    Adding Nutrient to your project

    Install the @nutrient-sdk/viewer package via npm. If you prefer, you can also download the SDK manually:

    Terminal window
    npm i @nutrient-sdk/viewer

    To run Nutrient Web SDK in the browser, copy the required library files (artifacts) to your assets folder:

    Terminal window
    cp -R ./node_modules/@nutrient-sdk/viewer/dist/ ./assets/

    Make sure your assets/ folder contains:

    • nutrient-viewer.js (entry point)
    • A nutrient-viewer-lib/ directory with the required runtime assets

    Integrating into your project

    1. Add the PDF document you want to display (e.g. document.pdf) to the root of your project. You can use our demo document as an example.

    2. Add an empty <div> element to your HTML where the viewer will mount:

      <div id="nutrient" style="height: 100vh;"></div>
    3. Import the SDK and initialize it using NutrientViewer.load():

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <title>Nutrient PDF Viewer</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    </head>
    <body>
    <div id="nutrient" style="height: 100vh;"></div>
    <script type="module">
    import "./assets/nutrient-viewer.js";
    const baseUrl = `${window.location.protocol}//${window.location.host}/assets/`;
    NutrientViewer.load({
    container: "#nutrient",
    document: "document.pdf",
    baseUrl,
    })
    .then((instance) => {
    console.log("Nutrient Viewer loaded", instance);
    })
    .catch((error) => {
    console.error(error.message);
    });
    </script>
    </body>
    </html>

    nutrient demo

    Adding highlight annotations programmatically

    To add highlight annotations programmatically, you’ll use the NutrientViewer.Annotations.HighlightAnnotation constructor function provided by Nutrient. This function enables you to create a new highlight annotation object with specific properties, such as the page index and the rectangles to highlight:

    NutrientViewer.load({
    container: "#nutrient",
    document: "document.pdf",
    baseUrl,
    })
    .then(async function (instance) {
    try {
    console.log("Nutrient loaded", instance);
    const rects = NutrientViewer.Immutable.List([
    new NutrientViewer.Geometry.Rect({
    left: 10,
    top: 120,
    width: 200,
    height: 10,
    }),
    new NutrientViewer.Geometry.Rect({
    left: 10,
    top: 150,
    width: 200,
    height: 10,
    }),
    ]);
    const annotation = new NutrientViewer.Annotations.HighlightAnnotation({
    pageIndex: 0,
    rects: rects,
    boundingBox: NutrientViewer.Geometry.Rect.union(rects),
    });
    await instance.create(annotation);
    console.log("Highlight annotation added successfully.");
    } catch (error) {
    console.error("Error adding highlight annotation:", error.message);
    }
    })
    .catch(function (error) {
    console.error("NutrientViewer failed to load:", error.message);
    });

    The provided rects array defines the bounding boxes of the areas to be highlighted, and the pageIndex property specifies the page where the highlight annotation will be added.

    Serving your website

    1. Install the serve package:

      Terminal window
      npm install --global serve
    2. Serve the contents of the current directory:

      Terminal window
      serve -l 8080 .
    3. Navigate to http://localhost:8080 to view the website.

    resulting image showing highlight annotation added to PDF

    Conclusion

    In this tutorial, you explored two methods to programmatically add highlight annotations to a PDF document. First, you learned how to use PDF.js(opens in a new tab) to retrieve existing highlight annotations from a PDF, offering a lightweight solution for accessing annotations in a web application. Next, you learned about Nutrient Web SDK, a commercial JavaScript PDF viewer library that provides advanced PDF editing capabilities, and you saw firsthand how to programmatically add highlight annotations using this powerful tool.

    To see a list of all web frameworks, you can contact our Sales team. Or, launch our demo to see our viewer in action.

    FAQ

    What is the main advantage of using Nutrient Web SDK over PDF.js for adding highlight annotations?

    Nutrient Web SDK provides advanced PDF editing features and a more robust annotation API, making it easier and more powerful for adding and managing highlight annotations compared to PDF.js.

    How do I integrate Nutrient Web SDK into my existing project?

    You can integrate Nutrient Web SDK by installing the @nutrient-sdk/viewer package via npm, adding it to your project, and initializing it in your JavaScript code with the NutrientViewer.load() method.

    Does Nutrient Web SDK support creating highlight annotations programmatically?

    Yes. Nutrient Web SDK supports programmatically creating highlight annotations using the NutrientViewer.Annotations.HighlightAnnotation constructor.

    Can I use PDF.js to manage highlight annotations effectively?

    PDF.js primarily focuses on PDF viewing and has limited capabilities for managing annotations when compared to Nutrient Web SDK.

    Hulya Masharipov

    Hulya Masharipov

    Technical Writer

    Hulya is a frontend web developer and technical writer at Nutrient who enjoys creating responsive, scalable, and maintainable web experiences. She’s passionate about open source, web accessibility, cybersecurity privacy, and blockchain.

    Explore related topics

    FREE TRIAL Ready to get started?