WebPDF

WebPDF puts PDF documents in web pages as HTML. Two custom elements do the work: <pdf-file> loads a document, and <pdf-page> shows one of its pages, with selectable text, working links and fillable forms. Pages are drawn by PDF.js, PDFium or as vector SVG, and the document's digital signatures are verified, all in the browser.

Concepts and usage

WebPDF brings PDFs into HTML the way <img> and <video> bring images and video: as elements you place, size and style like any other, with attributes for what you want and properties, methods and events for scripts.

Files and pages

A <pdf-file> loads one PDF document from a URL, from bytes or from the user's device. It draws nothing itself. A <pdf-page> shows one page of a file: the file its of attribute names, or the file it is nested in. One file serves any number of pages, so you can show the first page here, the last page there, and a whole document in a column:

html
<script src=//new.webpdf.pro/.js type=module></script>
<pdf-file id=report src=report.pdf></pdf-file>
<pdf-page of=report no=1></pdf-page>
<pdf-page of=report no=-1></pdf-page>

Files and pages are linked: load another document into the file, and every page shows it. Pages of the same file share its form values as you type.

Pages are documents, not pictures

A page draws its image with one of three renderers, PDF.js (the engine of Firefox), PDFium (the engine of Chrome) or SVG, and lays its text, links and form fields over it as real HTML. So you can select the text and find words in it, screen readers can read it, links work, and forms fill and save. See Choosing a renderer.

Sized like images

A page has the size of the PDF page, times its scale, the way an image has the size of its picture. Size it with CSS instead, and scale only sets how sharp it is drawn. Before its PDF arrives, a page already keeps a box of the right size, so nothing jumps, and lazy pages draw only when your readers reach them. See Lazy pages and placeholders.

Settings that cascade

Many attributes work on the WebPDF <script>, on a file and on a page: set controls on the script, and every page has controls; set controls=- on one page, and that page does not. These multi-homed attributes let you configure a whole site in one place. See Multi-homed attributes.

A viewer when you want one

Without attributes, a page is just the page. With controls, like a <video controls>, it becomes a viewer: keys to turn, rotate and zoom it, a bar on hover or tap, touch gestures, fullscreen, and a menu to switch the renderer, copy and save. See Viewer controls.

Forms, saving and exporting

Form fields in a page are real form controls. A file saves the filled PDF to the user's device, gives you its bytes to upload, and reads and writes the form values as XFDF. A page exports its image as PNG, WebP, JPEG, AVIF or SVG. See Forms and XFDF and Saving and exporting.

Signatures you can check

A signed file verifies its signatures by itself: whether the signed part is intact, who signed and when, whether a certificate path leads to an anchor you trust, and whether a certificate was revoked. Pages can show a card for each signature. You choose what to trust: your own root certificates, or well-known root stores such as the Adobe Approved Trust List and the EU trusted lists. See Verifying signatures.

Everything stays in the browser

Pages are drawn, forms are filled and saved, and signatures are checked in your visitor's browser. The PDF is never uploaded anywhere; checking a signature fetches certificate status and trust lists, never the document.

Your markup stays yours

<pdf-file> and <pdf-page> are standard custom elements, so they work anywhere HTML does, with or without a framework. They never add attributes or classes to your elements: their state is exposed as custom states, and their insides as parts and custom properties you can style. See Styling WebPDF.

The basic approach

Showing a PDF with WebPDF generally looks like this:

  1. Load WebPDF: <script src=//new.webpdf.pro/.js type=module></script>.
  2. Add a <pdf-file> with the src of your PDF and an id.
  3. Add a <pdf-page> for each page you want to show, naming the file with of and the page with no.
  4. Add attributes for what you need: controls, signatures, loading=lazy and so on, on the script, the file or a page.
  5. Script the elements through their properties, methods and events, and style them with CSS.

WebPDF works on any domain, with every feature; until a domain is licensed, its pages show a watermark. See Evaluation and licensing.

Guides

Using WebPDF

How to add WebPDF to a page, show pages, load files and work with the elements from JavaScript; with the events and browser support.

Multi-homed attributes

How attributes set on the <script>, a file and a page are inherited, add up and turn off.

Choosing a renderer

PDF.js, PDFium and SVG compared, and how to choose one per file, per page or while you read.

Viewer controls

The keys, the bar and the gestures of a page with controls, and how to tailor them.

Forms and XFDF

Filling forms, saving the filled PDF, and moving form data in and out as XFDF.

Saving and exporting

Saving PDFs to the device, getting their bytes, and exporting pages as images.

Verifying signatures

Checking digital signatures in the browser, choosing what to trust, and showing the results.

Lazy pages and placeholders

Drawing only the pages your readers reach, and keeping every page's box in place while its PDF loads.

Styling WebPDF

Sizing pages, coloring their paper, and styling their insides with parts, states and custom properties.

Evaluation and licensing

Where the evaluation watermark shows, and how to license a domain.

Reference

Elements

<pdf-file>

Loads a PDF document for pages to show; opens, saves, exports and verifies it.

<pdf-page>

Shows one page of a file, with selectable text, working links and fillable form fields.

<script>

The WebPDF loader, whose attributes set defaults for every file and page and switch built-in behaviors off.

Interfaces

PDFElement

The base of both elements: event names, placeholders and the controls they share.

PDFFileElement

The interface of <pdf-file>.

PDFPageElement

The interface of <pdf-page>.

PDFPageImageLayer

The image a page draws: its size and its export.

PDFPageAnnoLayer

The links and form fields of a page.

Signature verification results

The objects verify() returns, one per signature.

CSS

::part() names

The layers, links, fields, signature cards and controls of a page that you can style.

:state() names

The states of files and pages that you can select.

Custom properties

The colors and sizes you set, and the values a page sets for you.

Examples

Showing a page

The smallest use: one file, one page.

HTML

html
<script src=//new.webpdf.pro/.js type=module></script>
<pdf-file id=f src=//pdf.ist/web.pdf></pdf-file>
<pdf-page of=f scale=0.5></pdf-page>

Result

A viewer for a signed document

A page with controls, and a card for each signature of a file that trusts its demo root. Hover the page for its bar, or click it and press →.

HTML

html
<script src=//new.webpdf.pro/.js type=module controls signatures></script>
<pdf-file id=s src=//new.webpdf.pro/signed.pdf trust:src=//new.webpdf.pro/demo-root.pem></pdf-file>
<pdf-page of=s scale=0.6></pdf-page>

Result

Specifications

Not part of any specification. <pdf-file> and <pdf-page> are autonomous custom elements defined by WebPDF.pro. It implements:

Specification
HTML
# custom-elements
ISO 32000-2:2020 (PDF 2.0)
ISO 32000-2:2020 (PDF 2.0)
# 12.7 Forms
ISO 19444-1:2019 (XFDF)
ISO 32000-2:2020 (PDF 2.0)
# 12.8 Digital signatures
RFC 5652: Cryptographic Message Syntax
RFC 3161: Time-Stamp Protocol
RFC 5280: X.509 certificates and CRLs
RFC 6960: OCSP

Browser compatibility

desktopmobile
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
pdf-file
1251251531111812515383182712518
pdf-page
1251251531111812515383182712518
Opening and saving
1251251531111812515383182712518
Fullscreen
12512515311118125153831827125No
Signature verification
1251251531111812515383182712518
  • Opening and saving · Firefox, Safari, Chrome Android, Firefox for Android, Opera Android, Safari on iOS, Samsung Internet, WebView Android, WebView on iOS: Without the File System Access API (Chrome Android 132, Opera Android 87, Samsung Internet 29 and WebView Android 132 have it), opening falls back to <input type=file> and saving to a download.
  • Fullscreen · Safari on iOS: Only available on iPad, not on iPhone: there, toggleFullscreen() resolves to false.
  • Fullscreen · WebView on iOS: Not available: toggleFullscreen() resolves to false.
  • Signature verification · Chrome, Edge, Firefox, Opera, Safari, Chrome Android, Firefox for Android, Opera Android, Safari on iOS, Samsung Internet, WebView Android, WebView on iOS: Secure contexts (HTTPS) only; elsewhere every signature verifies as unknown.

Legend

Full support
Partial support
No support
See implementation notes.

See also