Blog Post

How to add annotations to PDFs using Angular

Illustration: How to add annotations to PDFs using Angular
Information

This article was first published in October 2023 and was updated in October 2024.

In this blog post, we’ll guide you through the process of adding annotations to PDFs in Angular using ngx-extended-pdf-viewer. In the first part, we’ll walk you through the steps to integrate ngx-extended-pdf-viewer into your project and demonstrate how to add annotations to a loaded PDF. In the second part, we’ll show you how to add annotations programmatically using Nutrient’s Angular PDF library.

Annotations allow users to collaborate on, mark up, and highlight important information within a PDF document. This can be incredibly useful for reviewing drafts, adding feedback, or making notes for future reference.

What is ngx-extended-pdf-viewer?

ngx-extended-pdf-viewer is a PDF viewer component for Angular applications. It extends the capabilities of the PDF.js library, allowing you to display, annotate, and interact with PDF files seamlessly.

Requirements

Before getting started, you’ll need:

When you install Node.js, npm is installed by default.

Setup

Go to your terminal and install the Angular command-line interface (CLI). This will help you get up and running quickly with Angular:

npm install -g @angular/cli

Now, open your favorite integrated development environment (IDE). This post uses Visual Studio Code.

Open the terminal and create a new Angular project:

ng new pdf-annotation-app

Choose No for adding Angular routing and CSS for the stylesheet.

Change your directory into the newly created folder:

cd pdf-annotation-app

Adding ngx-extended-pdf-viewer

Run the command below to install the ngx-extended-pdf-viewer library via npm or yarn. This will install the latest version of the library:

npm install ngx-extended-pdf-viewer
yarn add ngx-extended-pdf-viewer

Now you need to configure the angular.json file. You’ll add this configuration under the projects > yourProjectName > architect > build > options > assets section:

"assets": [
    "src/favicon.ico",
     "src/assets",
     {
      "glob": "**/*",
      "input": "node_modules/ngx-extended-pdf-viewer/assets/",
      "output": "/assets/"
     }
],

Go to the app.module.ts file and import NgxExtendedPdfViewerModule from ngx-extended-pdf-viewer and pass it to the imports array:

import { NgxExtendedPdfViewerModule } from 'ngx-extended-pdf-viewer';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, NgxExtendedPdfViewerModule],
  providers: [],
  bootstrap: [AppComponent],
  standalone: true,
})

Displaying a PDF

Add your PDF document to the src/assets directory. You can use our demo document as an example.

There’s one step left to see the PDF file in the browser. Go to the app.component.html file and replace the contents of app.component.html with:

<ngx-extended-pdf-viewer
	[src]="'assets/example.pdf'"
	[useBrowserLocale]="true"
	[textLayer]="true"
	[showHandToolButton]="true"
	[showPresentationModeButton]="true"
	[showDownloadButton]="false"
></ngx-extended-pdf-viewer>

There are many configuration options you can use. You can see all the options on the ngx-extended-pdf-viewer website.

Adding annotations

ngx-extended-pdf-viewer provides built-in tools for adding annotations like text comments, highlights, and drawings. Users can interact with these tools to annotate a PDF document.

Now, run your project with the following command:

npm start

Navigate to localhost:4200 to see your PDF file.

Information

You can access the project on GitHub.

ngx-extended-pdf-viewer demo

Nutrient’s Angular PDF annotation library

Nutrient’s Angular PDF annotation library provides a robust set of features:

  • 17 annotation types — Nutrient offers a wide range of annotation types, with even more on the horizon.
  • Customization — Tailor annotations to your needs by adjusting colors, shapes, and sizes.
  • Cross-device syncing — With server deployment, annotations can be synced seamlessly across multiple devices.
  • Real-time comment threads — Enable real-time conversations within documents, fostering collaboration (requires server deployment).
  • Customizable tooltips — Design tooltips to suit your specific requirements.
  • Framework support — Nutrient supports various web frameworks, eliminating the need to write APIs for different programming languages.

To explore the full capabilities of Nutrient and how it can enhance your project, take a look at our demo.

Integrating Nutrient with Angular

Now you’ll learn how to integrate Nutrient into your Angular project.

Creating a new Angular project

First, create a new Angular project for Nutrient integration:

ng new pspdfkit-web-example-angular

This will ask some configuration questions. Choose No for routing and CSS for the stylesheet.

Angular Project Configuration

Now, change your directory to this project:

cd pspdfkit-web-example-angular

Adding Nutrient

Install pspdfkit as a dependency with npm or yarn:

npm install pspdfkit
yarn add pspdfkit

Now, add the following to your angular.json file. Angular will copy the Nutrient library assets to the assets directory before running your app:

"assets": [
 "src/favicon.ico",
 "src/assets",
  {
 	   "glob": "**/*",
		"input": "./node_modules/pspdfkit/dist/pspdfkit-lib/",
		"output": "./assets/pspdfkit-lib/"
	}
]

Displaying the PDF

Add the PDF document you want to display to the src/assets directory. You can use our demo document as an example.

  1. Replace the contents of app.component.html with:

<div class="app">
	<div class="toolbar">
		Nutrient Angular Application
	</div>

	<!-- We'll mount the Nutrient UI to this element. -->
	<div class="pspdfkit-container"></div>
</div>
  1. Replace the contents of app.component.ts with:

import { Component } from '@angular/core';
import PSPDFKit from 'pspdfkit';

@Component({
	selector: 'app-root',
	templateUrl: './app.component.html',
	styleUrls: ['app.component.css'],
	standalone: true,
})
export class AppComponent {
	title = 'Nutrient Web SDK Angular Example';

	ngAfterViewInit(): void {
		PSPDFKit.load({
			// Use the assets directory URL as a base URL. Nutrient will download its library assets from here.
			baseUrl: location.protocol + '//' + location.host + '/assets/',
			document: '/assets/example.pdf',
			container: '.pspdfkit-container',
			licenseKey: 'YOUR_LICENSE_KEY_GOES_HERE', // Optional license key.
		}).then((instance) => {
			// For the sake of this demo, store the Nutrient Web SDK instance
			// on the global object so that you can open the dev tools and
			// play with the Nutrient API.

			(<any>window).instance = instance;
		});
	}
}

The license key is optional; however, you may see a watermark on your PDF files without a key. To get a key, contact Sales.

If you try to run your project, you may get an error stating the mounting container has no height. To fix this issue, add the following styles to the src/app/app.component.css file:

:host {
	height: 100%;
}

.app {
	position: fixed;
	width: 100%;
	height: 100%;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
}

.toolbar {
	position: relative;
	display: flex;
	align-items: center;
	height: 64px;
	width: 100%;
	padding: 0 24px;
	box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
	font-family: sans-serif;
	font-size: 20px;
	font-weight: 500;
	color: rgba(0, 0, 0, 0.8);
}

.logo {
	margin-right: 20px;
}

.pspdfkit-container {
	height: calc(100% - 64px);
}
Information

You can access the project on GitHub.

  1. Start the app and open it in your default browser:

npm start
yarn start

Adding text annotations to a PDF using Nutrient and Angular

Text annotations enable you to add comments, labels, or other textual information directly to a PDF document, enhancing its interactivity and usability.

Nutrient provides the PSPDFKit.Annotations.TextAnnotation class to create text annotations and customize them with various properties such as font, color, size, alignment, and position.

  1. Inside the app.component.ts file, add the createTextAnnotation method to add text annotations to the PDF:

async createTextAnnotation() {
		const annotation = new PSPDFKit.Annotations.TextAnnotation({
			pageIndex: 0, // Specify the page number for the annotation.
			text: {
				format: 'plain',
				value: 'Welcome to PSPDFKit', // Text to embed.
			},
			font: 'Helvetica',
			isBold: true,
			horizontalAlign: 'left', // Align the annotation to the left of the bounding box.
			boundingBox: new PSPDFKit.Geometry.Rect({
				left: 50, // Position of the annotation.
				top: 200,
				width: 100,
				height: 80,
			}),
			fontColor: PSPDFKit.Color.BLUE, // Color of the text.
		});

		// Attach this annotation to your PDF.
		const createdAnnotation = await this.pspdfkitInstance.create(
			annotation,
		);
		console.log('Text annotation created:', createdAnnotation);
	}
  1. Now that you’ve added the createTextAnnotation method, it should be called at the right moment. To ensure that the Nutrient instance is loaded and ready, invoke createTextAnnotation within the ngAfterViewInit lifecycle hook. Here’s the code to achieve this:

ngAfterViewInit(): void {
  PSPDFKit.load({
    baseUrl: location.protocol + "//" + location.host + "/assets/",
    document: "/assets/example.pdf",
    container: ".pspdfkit-container",
    licenseKey: "YOUR_LICENSE_KEY_GOES_HERE",
  }).then((instance) => {
    this.pspdfkitInstance = instance; // Store the Nutrient instance in a variable.

    // Call the function to create a text annotation.
    this.createTextAnnotation();
  });
}

When you run the application, you can see the text annotation added to the PDF.

Adding ink annotations to a PDF using Nutrient and Angular

To insert ink annotations into your Angular app using Nutrient, follow the steps below.

  1. Inside the app.component.ts file, add the following createInkAnnotation function. This method is responsible for creating an ink annotation on a PDF page. It takes four parameters — x1, y1, x2, and y2 — which represent the coordinates of the starting and ending points of the ink annotation:

async createInkAnnotation({
    x1,
    y1,
    x2,
    y2,
  }: {
    x1: number;
    y1: number;
    x2: number;
    y2: number;
  }) {
    const { List } = PSPDFKit.Immutable;
    const { DrawingPoint, Rect } = PSPDFKit.Geometry;
    const { InkAnnotation } = PSPDFKit.Annotations;

    const annotation = new InkAnnotation({
      pageIndex: 0,
      boundingBox: new Rect({ width: 400, height: 100 }),
      strokeColor: new PSPDFKit.Color({ r: 255, g: 0, b: 255 }),
      lines: List([
        List([
          new DrawingPoint({ x: x1, y: y1 }),
          new DrawingPoint({ x: x2, y: y2 }),
        ]),
      ]),
    });

    const createdAnnotation = await this.pspdfkitInstance.create(annotation);
    console.log("Ink annotation created:", createdAnnotation);
  }

  async addInkAnnotation() {
    await this.createInkAnnotation({
      x1: 5,
      y1: 5,
      x2: 100,
      y2: 100,
    });
  }
  1. Now, you need to call the createInkAnnotation method to actually create the ink annotation on your PDF. To ensure that this happens after the Nutrient instance is loaded, call it inside the ngAfterViewInit lifecycle hook:

ngAfterViewInit(): void {
  PSPDFKit.load({
    baseUrl: location.protocol + "//" + location.host + "/assets/",
    document: "/assets/example.pdf",
    container: ".pspdfkit-container",
    licenseKey: "YOUR_LICENSE_KEY_GOES_HERE",
  }).then((instance) => {
    this.pspdfkitInstance = instance; // Store the Nutrient instance in a variable.

    // Call the function to create an ink annotation.
    this.createInkAnnotation({
      x1: 5, // Starting x-coordinate.
      y1: 5, // Starting y-coordinate.
      x2: 100, // Ending x-coordinate.
      y2: 100, // Ending y-coordinate.
    });
  });
}

Conclusion

In this comprehensive post, you learned about two methods for annotating PDFs in your Angular application: one using ngx-extended-pdf-viewer for basic annotations, and the other leveraging Nutrient, a robust PDF SDK, to achieve advanced annotation functionalities, including text and ink annotations. By integrating these tools, you can develop interactive and collaborative PDF annotation features that greatly enhance your Angular applications.

If you’re interested in exploring Nutrient further, you can request a free trial of our SDK or visit our demo page to experience the capabilities of our product firsthand.

Author
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.

Related products
Share post
Free trial Ready to get started?
Free trial