Standalone, isolated, drop-in PDF viewer web component, based on PDF.js default viewer.
- Standalone isolated web component with no runtime dependencies
- Drop-in, iframe-based PDF.js default viewer for any web app
- Works with same-origin and cross-origin PDF documents
- Configure via attributes (page, zoom, search, pagemode, locale)
- Resource path attributes for PDF.js internals (
worker-src,c-map-url,icc-url,standard-font-data-url,wasm-url, and more) - Built-in worker is enabled by default for stricter CSP compatibility
- Configure
PDFViewerApplicationOptionsvia thesetViewerOptionsmethod - Access to
PDFViewerApplicationvia theinitPromiseproperty - Built-in Paper & Ink default theme, with theme control (automatic/light/dark) and custom CSS injection
- Locale override support using PDF.js viewer locales
- Supports all major browsers and most JS frameworks.
# With npm
npm install pdfjs-viewer-element
# With pnpm
pnpm add pdfjs-viewer-element<script type="module" src="https://cdn.jsdelivr.net/npm/pdfjs-viewer-element/dist/pdfjs-viewer-element.js"></script><pdfjs-viewer-element
src="https://alekswebnet.github.io/sample-pdf-with-images.pdf"
style="height: 100dvh">
</pdfjs-viewer-element>The element is block-level and needs an explicit height.
Play with attributes on API docs page.
Most attributes can be updated dynamically:
srcupdates by calling PDF.jsopen({ url })without rebuilding the viewer.page,search,phrase,zoom,pagemodeupdate via hash parameters.viewer-css-themeupdates the viewer theme at runtime.worker-src,debugger-src,c-map-url,icc-url,image-resources-path,sandbox-bundle-src,standard-font-data-url,wasm-urlupdate viewer options for subsequent document loads.localerebuilds the viewer so localization resources can be applied.
By default, the component uses the bundled worker (same-origin), which is CSP-friendly in strict script-src 'self' environments.
- Dev mode default:
./build/pdf.worker.mjs - Dist/default package default:
./pdf.worker.min.mjs
Set worker-src only if you want to serve the worker from a custom location (for example your own CDN or static assets path).
- The URL must point to a valid PDF.js module worker file.
- The worker version should match the bundled PDF.js version.
<pdfjs-viewer-element
src="/file.pdf"
worker-src="https://cdn.jsdelivr.net/npm/pdfjs-dist@6.2.108/build/pdf.worker.min.mjs">
</pdfjs-viewer-element>Use locale-src-template when you need to load localization files from a custom host.
- The template must include
{locale}. {locale}is replaced by thelocaleattribute value (for examplede,uk,en-US).- If
localeis not set, no locale file is loaded. - Changes to
locale-src-templateare applied when the viewer is (re)initialized, for example after setting/changinglocale.
Example:
<pdfjs-viewer-element
src="/file.pdf"
locale="de"
locale-src-template="https://cdn.example.com/pdfjs-locales/{locale}/viewer.ftl">
</pdfjs-viewer-element>The component includes and applies a default Paper & Ink theme from src/themes/paper-and-ink.css.
Use viewer-css-theme attribute to set light or dark theme manually:
<pdfjs-viewer-element
src="/file.pdf"
viewer-css-theme="DARK">
</pdfjs-viewer-element>Runtime example:
const viewerElement = document.querySelector('pdfjs-viewer-element')
viewerElement.setAttribute('viewer-css-theme', 'DARK')
viewerElement.setAttribute('viewer-css-theme', 'LIGHT')
viewerElement.setAttribute('viewer-css-theme', 'AUTOMATIC')You can override additional PDF.js viewer resource paths when needed:
<pdfjs-viewer-element
src="/file.pdf"
worker-src="/pdf.worker.min.mjs"
debugger-src="/debugger.mjs"
c-map-url="/cmaps/"
icc-url="/iccs/"
image-resources-path="/images/"
sandbox-bundle-src="/pdf.sandbox.mjs"
standard-font-data-url="/standard_fonts/"
wasm-url="/wasm/">
</pdfjs-viewer-element>You can add your own CSS rules to the viewer application using injectViewerStyles(styles: string):
<pdfjs-viewer-element id="viewer" src="/file.pdf">
</pdfjs-viewer-element>const viewerElement = document.querySelector('#viewer')
viewerElement.injectViewerStyles(`
#toolbarViewerMiddle, #toolbarViewerRight { display: none; }
`)injectViewerStyles(...) applies styles immediately when the viewer document is ready, and keeps them for future rebuilds.
injectViewerStyles(styles: string) - Adds custom CSS to the viewer now (when ready) and for future rebuilds.
const viewerElement = document.querySelector('pdfjs-viewer-element')
await viewerElement.injectViewerStyles(`
#toolbarViewerRight { display: none; }
#findbar { border-top: 2px solid #0200a8; }
`)initPromise: Promise<InitializationData> - Resolves after internal viewer is completely loaded and initialized, returning { viewerApp }, that gives a programmatic access to PDF.js viewer app (PDFViewerApplication).
const viewerElement = document.querySelector('pdfjs-viewer-element')
const { viewerApp } = await viewerElement.initPromise
viewerApp.open({ url: '/sample.pdf' })setViewerOptions(options: Record<string, string | number>): Promise<{ viewerOptions: IframeWindow['PDFViewerApplicationOptions'] }>
Updates PDF.js viewer options at runtime. Call this method with an object of key-value pairs to set options such as resource paths, rendering settings, or other PDFViewerApplicationOptions. Resolves after the viewer is initialized and returns the viewerOptions for testing purpose.
const viewerElement = document.querySelector('pdfjs-viewer-element')
await viewerElement.setViewerOptions({
enableComment: true,
enableSignatureEditor: true
})iframe: PdfjsViewerElementIframe - Public reference to the internal iframe element. Useful when you need direct access to contentWindow/contentDocument.
const viewerElement = document.querySelector('pdfjs-viewer-element')
// Access iframe window directly when needed.
const iframeWindow = viewerElement.iframe.contentWindow
// Read current location hash applied to the viewer.
console.log(iframeWindow.location.hash)
// Inspect iframe document title.
console.log(viewerElement.iframe.contentDocument.title)You can also react to source changes dynamically:
const viewerElement = document.querySelector('pdfjs-viewer-element')
viewerElement.setAttribute('src', '/another-file.pdf')Use iframe-title to add a title to the iframe element and improve accessibility.

