JSPM

@seba174/ng2-pdf-viewer

22.0.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 165
  • Score
    100M100P100Q84991F
  • License MIT

Angular 22+ standalone component for rendering PDF

Package Exports

  • @seba174/ng2-pdf-viewer
  • @seba174/ng2-pdf-viewer/package.json

Readme

Angular PDF Viewer

downloads npm version

PDF Viewer Component for Angular 22+ (standalone)

Maintenance

This fork continues the original API surface with current Angular and pdf.js tooling.

Overview

Install

Angular >= 22

npm install @seba174/ng2-pdf-viewer

Standalone component, signal-based inputs/outputs, ships with FESM2022 bundles.

Requirements

  • Angular 22.0.0 or newer.
  • Node 22.22.3+ / 24.15.0+ / 26+.
  • Modern browsers supported by Angular 22 and pdfjs-dist 6.x.

PDF.js assets

The viewer uses same-origin PDF.js assets by default. No CDN URLs are loaded by the library, and applications do not need a direct pdfjs-dist dependency just to serve the worker or cMaps.

Run the Angular schematic to configure the worker, cMaps, and viewer images:

ng add @seba174/ng2-pdf-viewer

If you configure assets manually, add these entries to the build target's assets array:

{
  "glob": "pdf.worker.min.mjs",
  "input": "node_modules/@seba174/ng2-pdf-viewer/assets/pdfjs/legacy/build",
  "output": "assets/pdfjs/legacy/build"
},
{
  "glob": "**/*",
  "input": "node_modules/@seba174/ng2-pdf-viewer/assets/pdfjs/cmaps",
  "output": "assets/pdfjs/cmaps"
},
{
  "glob": "**/*",
  "input": "node_modules/@seba174/ng2-pdf-viewer/assets/pdfjs/web/images",
  "output": "assets/pdfjs/web/images"
}

The default runtime paths are resolved against the document base URL:

  • worker: assets/pdfjs/legacy/build/pdf.worker.min.mjs
  • cMaps: assets/pdfjs/cmaps/
  • viewer images: assets/pdfjs/web/images/

Configuration

Most applications do not need runtime configuration. If your app serves PDF.js assets from a different path, configure the viewer once during bootstrap:

import { providePdfViewer } from '@seba174/ng2-pdf-viewer';

bootstrapApplication(AppComponent, {
  providers: [
    providePdfViewer({
      workerSrc: '/static/pdfjs/pdf.worker.min.mjs',
      cMapsUrl: '/static/pdfjs/cmaps/',
      imageResourcesPath: '/static/pdfjs/web/images/'
    })
  ]
});

Relative values are resolved against the document base URL.

Usage

Add PdfViewerComponent to the imports array of the standalone component where you want to render a PDF.

import { Component } from '@angular/core';
import { PdfViewerComponent } from '@seba174/ng2-pdf-viewer';

@Component({
  selector: 'example-app',
  imports: [PdfViewerComponent],
  template: `
    <pdf-viewer
      [src]="pdfSrc"
      [render-text]="true"
      [original-size]="false"
      style="width: 400px; height: 500px"
    />
  `
})
export class AppComponent {
  pdfSrc = "./assets/pdf-test.pdf";
}

Zoneless support

PdfViewerComponent works in both zone-based and zoneless host applications. The component has no reactive template bindings — its template is a single container <div> and all rendering is delegated to pdf.js's imperative DOM API. Outputs go through output() signals, which automatically mark consumer components dirty.

Zoneless consumers can bootstrap as usual:

import { bootstrapApplication } from '@angular/platform-browser';
import { provideZonelessChangeDetection } from '@angular/core';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent, {
  providers: [provideZonelessChangeDetection()]
}).catch(err => console.error(err));

No additional configuration is required on the library side.

Options

[src]

Property Type Required
[src] string, object, Uint8Array Required

Pass pdf location

[src]="'./assets/pdf-test.pdf'"

For more control you can pass options object to [src]. See other attributes for the object here.

Options object for loading protected PDF would be:

{
 url: './assets/pdf-test.pdf',
 withCredentials: true
}

[page]

Property Type Required
[page] or [(page)] number Required with [show-all]="false" or Optional with [show-all]="true"

Page number

[page]="1"

supports two way data binding as well

[(page)]="pageVariable"

If you want that the two way data binding actually updates your page variable on page change/scroll - you have to be sure that you define the height of the container, for example:

pdf-viewer {
    height: 100vh;
}

[stick-to-page]

Property Type Required
[stick-to-page] boolean Optional

Sticks view to the page. Works in combination with [show-all]="true" and page.

[stick-to-page]="true"

[render-text]

Property Type Required
[render-text] boolean Optional

Enable text rendering, allows to select text

[render-text]="true"

[render-text-mode]

Property Type Required
[render-text-mode] RenderTextMode Optional

Used in combination with [render-text]="true"

Controls if the text layer is enabled, and the selection mode that is used.

0 = RenderTextMode.DISABLED - disable the text selection layer

1 = RenderTextMode.ENABLED - enables the text selection layer

2 = RenderTextMode.ENHANCED - enables enhanced text selection

[render-text-mode]="1"
Property Type Required
[external-link-target] string Optional

Used in combination with [render-text]="true"

Link target

  • blank
  • none
  • self
  • parent
  • top
[external-link-target]="'blank'"

[rotation]

Property Type Required
[rotation] number Optional

Rotate PDF

Allowed step is 90 degree, ex. 0, 90, 180

[rotation]="90"

[zoom]

Property Type Required
[zoom] number Optional

Zoom pdf

[zoom]="0.5"

[zoom-scale]

Property Type Required
[zoom-scale] 'page-width'|'page-fit'|'page-height' Optional

Defines how the Zoom scale is computed when [original-size]="false", by default set to 'page-width'.

  • 'page-width' with zoom of 1 will display a page width that take all the possible horizontal space in the container

  • 'page-height' with zoom of 1 will display a page height that take all the possible vertical space in the container

  • 'page-fit' with zoom of 1 will display a page that will be scaled to either width or height to fit completely in the container

[zoom-scale]="'page-width'"

[original-size]

Property Type Required
[original-size] boolean Optional
  • if set to true - size will be as same as original document
  • if set to false - size will be as same as container block
[original-size]="true"

[fit-to-page]

Property Type Required
[fit-to-page] boolean Optional

Works in combination with [original-size]="true". You can show your document in original size, and make sure that it's not bigger then container block.

[fit-to-page]="false"

[show-all]

Property Type Required
[show-all] boolean Optional

Show single or all pages altogether

[show-all]="true"

[autoresize]

Property Type Required
[autoresize] boolean Optional

Turn on or off auto resize.

!Important To make [autoresize] work - make sure that [original-size]="false" and pdf-viewer tag has max-width or display are set.

[autoresize]="true"

[c-maps-url]

Property Type Required
[c-maps-url] string Optional

Url for non-latin characters source maps.

[c-maps-url]="'assets/pdfjs/cmaps/'"

Default url is assets/pdfjs/cmaps/, resolved against the document base URL. You can also set the application default with providePdfViewer({ cMapsUrl }).

To use a different path, copy node_modules/@seba174/ng2-pdf-viewer/assets/pdfjs/cmaps to your chosen assets folder and pass that path to [c-maps-url].

[show-borders]

Property Type Required
[show-borders] boolean Optional

Show page borders

[show-borders]="true"

(after-load-complete)

Property Type Required
(after-load-complete) callback Optional

Get PDF information with callback

First define callback function "callBackFn" in your controller,

callBackFn(pdf: PDFDocumentProxy) {
   // do anything with "pdf"
}

And then use it in your template:

(after-load-complete)="callBackFn($event)"

(page-rendered)

Property Type Required
(page-rendered) callback Optional

Get event when a page is rendered. Called for every page rendered.

Define callback in your component:

pageRendered(e: CustomEvent) {
  console.log('(page-rendered)', e);
}

And then bind it to <pdf-viewer>:

(page-rendered)="pageRendered($event)"

(pages-initialized)

Property Type Required
(pages-initialized) callback Optional

Get event when the pages are initialized.

Define callback in your component:

pageInitialized(e: CustomEvent) {
  console.log('(pages-initialized)', e);
}

And then bind it to <pdf-viewer>:

(pages-initialized)="pageInitialized($event)"

(text-layer-rendered)

Property Type Required
(text-layer-rendered) callback Optional

Get event when a text layer is rendered.

Define callback in your component:

textLayerRendered(e: CustomEvent) {
  console.log('(text-layer-rendered)', e);
}

And then bind it to <pdf-viewer>:

(text-layer-rendered)="textLayerRendered($event)"

(error)

Property Type Required
(error) callback Optional

Error handling callback

Define callback in your component's class

onError(error: any) {
  // do anything
}

Then add it to pdf-component in component's template

(error)="onError($event)"

(on-progress)

Property Type Required
(on-progress) callback Optional

Loading progress callback - provides progress information total and loaded bytes. Is called several times during pdf loading phase.

Define callback in your component's class

onProgress(progressData: PDFProgressData) {
  // do anything with progress data. For example progress indicator
}

Then add it to pdf-component in component's template

(on-progress)="onProgress($event)"

Render local PDF file

In your html template add input:

<input (change)="onFileSelected()" type="file" id="file">

and then add onFileSelected method to your component:

onFileSelected() {
  let $img: any = document.querySelector('#file');

  if (typeof (FileReader) !== 'undefined') {
    let reader = new FileReader();

    reader.onload = (e: any) => {
      this.pdfSrc = e.target.result;
    };

    reader.readAsArrayBuffer($img.files[0]);
  }
}

Search in the PDF

Use eventBus for the search functionality.

In your component's ts file:

  • Add a signal viewChild() reference to pdf-viewer,
  • then when needed execute search() like this:
import { Component, viewChild } from '@angular/core';
import { PdfViewerComponent } from '@seba174/ng2-pdf-viewer';

@Component({ /* ... */ })
export class AppComponent {
  private readonly pdfComponent = viewChild(PdfViewerComponent);

  search(stringToSearch: string) {
    this.pdfComponent()?.eventBus.dispatch('find', {
      query: stringToSearch, type: 'again', caseSensitive: false, findPrevious: undefined, highlightAll: true, phraseSearch: true
    });
  }
}

The legacy @ViewChild(PdfViewerComponent) private pdfComponent: PdfViewerComponent; decorator form still works but viewChild() is the modern API and matches Angular's signal direction.

Contribute

See CONTRIBUTING.md

License

MIT