{"id":18828400,"url":"https://github.com/dealfonso/pdfjs-viewer","last_synced_at":"2025-05-11T21:14:22.384Z","repository":{"id":118337936,"uuid":"437320981","full_name":"dealfonso/pdfjs-viewer","owner":"dealfonso","description":"A viewer based on PDFjs, which can be embedded in any web page (not using iframes)","archived":false,"fork":false,"pushed_at":"2025-03-01T15:09:04.000Z","size":333,"stargazers_count":71,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-11T21:14:16.869Z","etag":null,"topics":["html","javascript","jquery","pdf","pdf-viewer","pdfjs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dealfonso.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-11T15:38:53.000Z","updated_at":"2025-04-13T12:36:49.000Z","dependencies_parsed_at":"2025-01-15T12:19:45.380Z","dependency_job_id":"505dec7a-52df-4a66-ba5b-869ca36c4145","html_url":"https://github.com/dealfonso/pdfjs-viewer","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealfonso%2Fpdfjs-viewer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealfonso%2Fpdfjs-viewer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealfonso%2Fpdfjs-viewer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealfonso%2Fpdfjs-viewer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dealfonso","download_url":"https://codeload.github.com/dealfonso/pdfjs-viewer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253633147,"owners_count":21939392,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","javascript","jquery","pdf","pdf-viewer","pdfjs"],"created_at":"2024-11-08T01:24:55.265Z","updated_at":"2025-05-11T21:14:22.332Z","avatar_url":"https://github.com/dealfonso.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![](https://data.jsdelivr.com/v1/package/gh/dealfonso/pdfjs-viewer/badge?style=rounded)](https://www.jsdelivr.com/package/gh/dealfonso/pdfjs-viewer) ![](https://img.shields.io/github/v/release/dealfonso/pdfjs-viewer) ![](https://img.shields.io/github/release-date/dealfonso/pdfjs-viewer) ![](https://img.shields.io/github/languages/code-size/dealfonso/pdfjs-viewer) ![](https://img.shields.io/github/license/dealfonso/pdfjs-viewer)\n\n# PDFjs-viewer\n\nThe distribution of [Mozilla's PDF.js](https://mozilla.github.io/pdf.js/) includes an example of a viewer that can be used in a web page by means of inserting using an `iframe`. But the viewer cannot be easily used or customized for using it as part of a web application.\n\nPDFjs-viewer is an embeddable and easily customizable PDF viewer that is implemented using the PDF.js library. \n\nSo, if you have a `div` in your web application, you can convert it into a PDF viewer as in the next example:\n\n```html\n\u003cdiv class=\"pdfjs-viewer\"\u003e\n\u003c/div\u003e \n\u003cscript\u003e\nlet pdfViewer = new PDFjsViewer($('.pdfjs-viewer'));\npdfViewer.loadDocument(\"https://github.com/dealfonso/pdfjs-viewer/raw/main/examples/test.pdf\");\n\u003c/script\u003e\n```\n\nor even easier\n\n```html\n\u003cdiv class=\"pdfjs-viewer\" pdf-document=\"https://github.com/dealfonso/pdfjs-viewer/raw/main/examples/test.pdf\" initial-zoom=\"fit\"\u003e\n```\n\nThe PDFjsViewer is customizable and has different options and callbacks that enable it to be easily integrated in your application.\n\nSome examples included in the distribution:\n- A simple PDF viewer, for a simple document.\n- A simpler PDF viewer, using the declarative way (i.e. setting the _pdfjs-viewer_ class to any object).\n- A PDF viewer with a toolbar that enables navigation through the document.\n- A PDF viewer with thumbnails that interact with the main document.\n- A PDF viewer in which it is possible to create selections and move them across different pages.\n\n**DISCLAIMER:** _PDFjs-viewer is written from scratch and has nothing to do with the example viewer in the PDF.js distribution._\n\n## Is PDFjs-viewer for me?\n\nWell, if you need a PDF viewer in your web application, you can try to embed the viewer that comes in the [PDF.js distribution](https://github.com/mozilla/pdf.js) in an `iframe`. It is well-supported and has a lot of background.\n\nBut if (as in my case) you need more than simply a PDF viewer embedded in an `iframe`: you need to draw in the pages of the PDF, need to add more features to your viewer, customize the style, etc., PDFjs-viewer is worth a try. \n\n\u003e The origin of PDFjs-viewer was to enable drawing a selection over the pages, to add a digital signature with an external application.\n\n### Technical facts\n\n- The pages of each document are rendered on demand, to avoid having all the pages using the memory of the browser. The viewer detects the visible pages, and renders each of them. Although rendering is fast, using the options (i.e. `extraPagesToLoad`) it is advisable to render some extra pages to enable a better user experience when scrolling the document.\n- PDFjs-viewer adds some callbacks that are called upon different events: `onDocumentReady`, `onNewPage`, `onPageRender`, `onZoomChange`, `onActivePageChanged`. Each callback is binded to the PDFjsViewer instance, so it is possible to use `this` to refer to it.\n- PDFjs-viewer renders the pages according to the size of the DIVs in which they are included. In this way, the amount of memory is adjusted to the minimum needed. `PDFjsViewer` considers the `pixel_ratio` feature to increase the resolution of the images according to the features of the device in which the document has been opened (e.g. retina displays and so on).\n- PDFjs-viewer includes support for zooming the pages so that the user does not need to deal with this typical feature.\n\n## Using\n\n### Dependencies\nPDFjs-viewer depends on Mozilla's [PDF.js library](https://mozilla.github.io/pdf.js). So please be sure to include the dependencies in your project:\n\n```html\n\u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\nvar pdfjsLib = window['pdfjs-dist/build/pdf'];\npdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';\n\u003c/script\u003e\n```\n\nPDFjs-viewer also depends on a [jQuery](https://jquery.com/) compatible library, so please include it in your project before including the PDFjs-viewer library:\n\n```html\n\u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js\"\u003e\u003c/script\u003e\n```\n\n#### Troubleshooting\nSome users have reported problems with jQuery. So I added support for an alternative library called [nojquery](https://github.com/jsutilslib/nojquery). If you want to use this library instead, please include it before the PDFjs-viewer library.\n\n**nojquery** is a library that provides a subset of jQuery functions that are used in PDFjs-viewer. It is a lightweight library that can be used as a replacement for jQuery in some cases. `PDFjs-viewer` will use `nojquery` with more priority than jQuery if it is included in the project.\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/gh/jsutilslib/nojquery/nojquery.min.js\"\u003e\u003c/script\u003e\n```\n\n### From source\n\nThere is a single _javascript_ file that contains the whole PDFjsViewer class (in folder `js`).\n\nThere are also a set of _css_ files that contain some styles to be used in the library and examples. These files can also be included individually in your project, or combined into a single file by concatenating them.\n\nA `Makefile` is provided to create the single all-in-one minified `js` and `css` files for the library.\n\n```console\n# npm install -g uglify-js clean-css-cli\n...\n# git clone https://github.com/dealfonso/pdfjs-viewer\n# cd pdfjs-viewer\n# make\nuglifyjs js/*.js  -b | cat notice - \u003e pdfjs-viewer.js\nuglifyjs js/*.js  | cat notice.min - \u003e pdfjs-viewer.min.js\ncleancss css/*.css --format beautify | cat notice - \u003e pdfjs-viewer.css\ncleancss css/*.css | cat notice.min - \u003e pdfjs-viewer.min.css\n```\n\nNow you can use files `pdfjs-viewer.min.js` and `pdfjs-viewer.min.css` in your project (jQuery or nojquery is a prerequisite):\n\n```html\n\u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"pdfjs-viewer.min.js\"\u003e\u003c/script\u003e\n\u003clink rel=\"stylesheet\" href=\"pdfjs-viewer.min.css\"\u003e\n```\n\n### From a CDN\n\nIt is possible to use `pdfjs-viewer` directly from a CDN:\n\n```html\n\u003cscript src=\"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/gh/dealfonso/pdfjs-viewer@2.0/dist/pdfjs-viewer.min.js\"\u003e\u003c/script\u003e\n\u003clink rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/dealfonso/pdfjs-viewer@2.0/dist/pdfjs-viewer.min.css\"\u003e\n```\n\n## API\n\nThe creation of a PDF viewer consists of creating a `PDFjsViewer` object, setting the object in which the PDF viewer should be set, and configuring the options that we may need.\n\n```javascript\nvar options = { \n    ...\n};\nvar pdfViewer = new PDFjsViewer(document.querySelector('.pdfjs-viewer'), options);\n```\n\n### Options\n\nThe possible option values along with the default values are the next (the comments in the code are self-explanatory):\n```javascript\n// Fraction of the area of the page that has to be visible to be considered that it is visible\nvisibleThreshold: 0.5,\n// Number of pages to load appart from the currently visible one (to enable fast scrolling)\nextraPagesToLoad: 3,\n// The class used for each page (the div that wraps the content of the page)\npageClass: \"pdfpage\",\n// Prefix of the id used for each page (the page id will be \u003cpageIdPrefix\u003e-\u003cpage number\u003e)\npageIdPrefix: \"page\",\n// The class used for the content of each page (the div that contains the page)\ncontentClass: \"content-wrapper\",\n// Posible zoom values to iterate over using \"in\" and \"out\"\nzoomValues: [ 0.25, 0.5, 0.75, 1, 1.25, 1.50, 2, 4, 8 ],\n// Percentage of the container that will be filled with the page\nzoomFillArea: 0.95,\n// Function called when a document has been loaded and its structure has been created\nonDocumentReady: () =\u003e {},\n// Function called when a new page is created (it is bound to the object, and receives an html object as parameter, and the page number)\nonNewPage: (page, i) =\u003e {},\n// Function called when a page is rendered (it is bound to the object, and receives an html object as parameter, and the page number)\nonPageRender: (page, i) =\u003e {},\n// Function called when the zoom level changes (it receives the zoom level)\nonZoomChange: (zoomlevel) =\u003e {},\n// Function called whenever the active page is changed (the active page is the one that is shown in the viewer)\nonActivePageChanged: (page, i) =\u003e {},\n// Function called to get the content of an empty page\nemptyContent: () =\u003e $('\u003cdiv class=\"loader\"\u003e\u003c/div\u003e')\n// The scale to which the pages are rendered (1.5 is the default value for the PDFjs viewer); a higher value will render the pages with a higher resolution\n//   but it will consume more memory and CPU. A lower value will render the pages with a lower resolution, but they will be uglier.\nrenderingScale: 1.5,\n```\n\n### Methods\n\nThe public methods of the PDFViewer class are the next:\n\n- `loadDocument(document)`: Loads the document and returns a promise to load it (and so the result is _thenable_ to add actions after loading the document, or is _catchable_ in case of error). The `document` can be either an _url_ or a _bin array_.\n- `forceViewerInitialization()`: Forces the creation (or re-creation) of the whole content of the viewer (i.e. new divs, structures, etc.). It is usefull for full refresh of the viewer (e.g. when changes the rotation of the pages).\n- `refreshAll()`: Recalculates which pages are now visible and forces redrawing them.\n- `getActivePage()`: Gets the jQuery div object corresponding to the active page (or null, if none of the pages have been set).\n- `first()`: Scrolls to the first page of the document.\n- `last()`: Scrolls to the last page of the document.\n- `next()`: Scrolls to the next page (if any).\n- `prev()`: Scrolls to the previous page (if any).\n- `getPageCount()`: Gets the number of pages of the document.\n- `getPages()`: Retrieves all the pages of the document (the pageinfo structures).\n- `scrollToPage(i)`: Sets the scroll position of the container to page number `i`\n- `isPageVisible(i)`: Returns true if page number `i` is considered to be visible \n- `setZoom(zoom)`: Sets the current zoom level and applies it to all the pages (it is possible to use a float value which represents a fraction or a keyword 'in', 'out', 'width', 'height' or 'fit').\n- `getZoom()`: Obtain the current zoom level\n- `rotate(deg, accumulate = false)`: Rotates the pages of the document `deg` degrees (if `accumulate` is set to `false`), or increases the rotation by `deg` degrees (if `accumulate` is set to `true`).\n\n## Declarative\n\nIf simply need a PDF viewer in a _div_, you can use the declarative way, which means that whenever an object is declared with class `pdfjs-viewer`, it is attached a `PDFjsViewer` object as the property `pdfViewer` of the HTML object.\n\nSo it is possible to use a tag like the next one:\n\n```html\n\u003cdiv id=\"viewer\" class=\"pdfjs-viewer\" pdf-document=\"https://github.com/dealfonso/pdfjs-viewer/raw/main/examples/test.pdf\" initial-zoom=\"fit\"\u003e\n```\n\nAnd the div will automatically load the pdf file and when loaded, it will zoom to fit the first page.\n\nNow if we get the object is obtained in _javascript_, the `pdfViewer` property will contain the object.\n\n```javascript\nlet viewer = document.getElementById(\"viewer\");\nconsole.log(viewer.pdfViewer);\n```\n\nThe rest of options in the API section can also be set as parameters for this tag as _snake-case_. For example, it is possible to add an `onDocumentReady` handler in the next way:\n\n```html\n\u003cdiv class=\"pdfjs-viewer\" pdf-document=\"https://github.com/dealfonso/pdfjs-viewer/raw/main/examples/test.pdf\" initial-zoom=\"fit\" on-document-ready=\"pdfViewer = this.pdfViewer\"\u003e\n```\n\n## Examples\n\n### Example 1 - the most simple example\n\nThe most simple example is to include a PDF viewer as the whole body of the web application:\n\n```html\n\u003cscript\u003e\n    var pdfViewer = new PDFjsViewer($('body'));\n    pdfViewer.loadDocument('test.pdf');\n\u003c/script\u003e\n```\n\nIn this example, the whole page will be a PDF viewer showing document _test.pdf_.\n\n![example 1](img/ex1.png)\n\nCheck the example at [PDFjs-viewer example-1](https://codepen.io/dealfonso/pen/QWqMJwp)\n\n### Example 2 - a viewer in a DIV\n\nTo create a viewer in a DIV, it is needed to add class `pdfjs-viewer` class to the div.\n\nIn this snippet, we are also using some of the callbacks that PDFjs-viewer provides, to update parts of our interface.\n\n```html\n\u003cdiv class=\"row h-100\"\u003e\n  \u003cdiv class=\"col-12 text-center\"\u003e\n    \u003ch1\u003eExample for PDFjs-viewer\u003c/h1\u003e\n    \u003cp\u003eThis is a simple document embeded in a div (integrated with bootstrap)\u003c/p\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"row col-6 offset-sm-3 pdfviewer p-0 row h-100\"\u003e\n    \u003cdiv class=\"pdfjs-toolbar text-center row m-0 p-0\"\u003e\n        ...\n    \u003c/div\u003e\n    \u003cdiv class=\"pdfjs-viewer h-100\"\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n\u003cscript type=\"text/javascript\"\u003e\nlet pdfViewer = new PDFjsViewer($(\".pdfjs-viewer\"), {\n  onZoomChange: function (zoom) {\n    zoom = parseInt(zoom * 10000) / 100;\n    $(\".zoomval\").text(zoom + \"%\");\n  },\n  onActivePageChanged: function (page, pageno) {\n    $(\".pageno\").text(pageno + \"/\" + this.getPageCount());\n  }\n});\npdfViewer\n  .loadDocument(\n    \"https://cdn.jsdelivr.net/gh/dealfonso/pdfjs-viewer/examples/test.pdf\"\n  )\n  .then(function () {\n    pdfViewer.setZoom(\"fit\");\n  });\n\u003c/script\u003e\n```\n\n![example 2](img/ex2.png)\n\nCheck the example at [PDFjs-viewer example-2](https://codepen.io/dealfonso/pen/qBPPEEd)\n\n### Example 3 - a document with thumbnails and a toolbar\n\nEach of the PDFjsViewer objects is independent from each other, so it is possible to include multiple PDF documents in the same web application.\n\nIn this example, we have included two independent documents (which at the end, have the same PDF source): one to act as thumbnails and other to act as the main document. Then using the callbacks, it is possible to make them interact one with the other to mark the _active page_ in the thumbnails when scrolling the main document, or showing a specific page when clicking on one of the pages in the thumbnails documents.\n\n![example 3](img/ex3.png)\n\nCheck the example at [PDFjs-viewer example-3](https://codepen.io/dealfonso/pen/dyVVYgP)\n\n## Collaborations\n\nI really appreciate collaborations either by detecting bugs or by suggesting new features for this project. In this case, you can open issues and I'll try to address them in a best-effort basis.\n\nAlso I welcome collaborations for enhancing the viewer. So if you can add new features, please fork the project and create pull requests. In this case, please add documentation about the new features both in the documentation as in the pull-request description.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdealfonso%2Fpdfjs-viewer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdealfonso%2Fpdfjs-viewer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdealfonso%2Fpdfjs-viewer/lists"}