@capgo/capacitor-pdf-viewer
v8.2.7
Published
Capacitor plugin for opening PDFs inside the app.
Readme
@capgo/capacitor-pdf-viewer
🤖 Building with an AI coding agent? Install Capgo skills so Claude Code, Codex, Cursor, Copilot, or Gemini CLI know how to install and use
@capgo/capacitor-pdf-viewerin your Capacitor app:npx skills add Cap-go/capgo-skills. Then ask your agent: "Add @capgo/capacitor-pdf-viewer to my Capacitor app and wire it up." Agent setup guides · Hosted MCP
@capgo/capacitor-pdf-viewer embeds native PDF viewing in Capacitor apps on iOS, Android, and web. Instead of fighting WebView limitations or shipping a heavy JavaScript PDF renderer, you open files from a path, HTTPS URL (with custom headers), or base64 and get system-grade rendering: page navigation, pinch zoom, continuous or single-page scrolling, password-protected documents, fullscreen or inline layout, and events for load, errors, page changes, link taps, and close. On iOS it uses PDFKit; on Android it uses Pdfium; on web it uses the browser PDF viewer with blob URLs.
Features
- Open PDFs from a device path,
file://URL, HTTPS URL, or base64 (includingdata:URIs) - Optional
headerswhen downloading remote URLs (auth tokens, cookies) - Password support for encrypted PDFs on iOS and Android
- Fullscreen overlay or inline mode anchored to a DOM element (
elementId) - Continuous vertical scrolling or single-page mode
- Programmatic goToPage, setZoom, and close
- Events:
load,pageChange,error,close,linkTap
Use cases
- Invoices, manuals, and tickets stored on device or returned from your API as base64
- Authenticated document download from a signed URL with custom HTTP headers
- Embedded PDF preview in a form or dashboard region (inline mode)
- Guided reading flows that jump to a page and listen for link taps inside the PDF
Documentation
- Plugin docs on capgo.app
- Tutorial with install steps and examples
- Capgo for live updates, native builds, and plugin support
Compatibility
| Plugin version | Capacitor compatibility | Maintained | | -------------- | ----------------------- | ---------- | | v8.*.* | v8.*.* | ✅ | | v7.*.* | v7.*.* | On demand | | v6.*.* | v6.*.* | On demand |
Policy:
- New plugins start at version
8.0.0(Capacitor 8 baseline). - Backward compatibility for older Capacitor majors is supported on demand.
Install
npm i @capgo/capacitor-pdf-viewer
npx cap syncWith Bun:
bun add @capgo/capacitor-pdf-viewer
bunx cap synciOS setup
No extra Info.plist keys or entitlements are required by this plugin. It uses Apple PDFKit. Remote PDFs use URLSession with the headers you pass in open. For HTTPS URLs, follow your app's usual App Transport Security rules.
Android setup
The plugin library targets minSdk 24 (Android 7.0) and bundles Pdfium (io.legere:pdfiumandroid). The plugin AndroidManifest.xml is empty: it does not declare INTERNET, storage, or FileProvider entries. If you open https sources, add INTERNET to your app manifest:
<uses-permission android:name="android.permission.INTERNET" />Local files and base64 do not need extra permissions beyond what your app already uses to read those paths.
Web
No Capacitor sync steps are required for web. URL sources are fetched with your headers; setZoom is a no-op because zoom is controlled by the browser viewer. Passwords cannot be injected on web; the browser may prompt on its own.
Usage
import { PdfViewer } from '@capgo/capacitor-pdf-viewer';
await PdfViewer.addListener('pageChange', ({ page, pageCount }) => {
console.log(`Page ${page} of ${pageCount}`);
});
const { pageCount, page } = await PdfViewer.open({
source: 'https://example.com/manual.pdf',
headers: { Authorization: 'Bearer YOUR_TOKEN' },
mode: 'fullscreen',
scrollMode: 'continuous',
page: 1,
});
await PdfViewer.goToPage({ page: 2 });
await PdfViewer.setZoom({ scale: 1.25 });
await PdfViewer.close();Inline preview in a div:
await PdfViewer.open({
source: base64FromYourApi,
sourceType: 'base64',
mode: 'inline',
elementId: 'pdf-host',
});Password-protected file (iOS and Android):
await PdfViewer.open({
source: '/path/on/device/encrypted.pdf',
sourceType: 'path',
password: 'secret',
});On native shells, loading a PDF from the WebView origin URL often fails because that origin is not a real file server. Fetch the bytes in JavaScript and pass sourceType: 'base64' instead (see example-app/).
API
open(...)close()goToPage(...)setZoom(...)getPluginVersion()addListener('load', ...)addListener('pageChange', ...)addListener('error', ...)addListener('close', ...)addListener('linkTap', ...)- Interfaces
- Type Aliases
Native PDF viewer for Capacitor (PDFKit on iOS, Pdfium on Android, browser viewer on web).
open(...)
open(options: OpenPdfOptions) => Promise<OpenPdfResult>Open a PDF from a file, path, URL, or base64 source.
| Param | Type |
| ------------- | --------------------------------------------------------- |
| options | OpenPdfOptions |
Returns: Promise<OpenPdfResult>
Since: 8.0.0
close()
close() => Promise<void>Close the active viewer and remove any overlay.
Since: 8.0.0
goToPage(...)
goToPage(options: GoToPageOptions) => Promise<void>Jump to a 1-based page number in the open document.
| Param | Type |
| ------------- | ----------------------------------------------------------- |
| options | GoToPageOptions |
Since: 8.0.0
setZoom(...)
setZoom(options: SetZoomOptions) => Promise<void>Set the zoom scale multiplier (1 is the default fit scale on native).
On web this resolves without changing the browser viewer zoom.
| Param | Type |
| ------------- | --------------------------------------------------------- |
| options | SetZoomOptions |
Since: 8.0.0
getPluginVersion()
getPluginVersion() => Promise<PluginVersionResult>Get the native or web implementation version marker.
Returns: Promise<PluginVersionResult>
Since: 8.0.0
addListener('load', ...)
addListener(eventName: 'load', listenerFunc: (event: PdfLoadEvent) => void) => Promise<PluginListenerHandle>Listen for successful PDF load.
| Param | Type |
| ------------------ | ------------------------------------------------------------------------- |
| eventName | 'load' |
| listenerFunc | (event: PdfLoadEvent) => void |
Returns: Promise<PluginListenerHandle>
Since: 8.0.0
addListener('pageChange', ...)
addListener(eventName: 'pageChange', listenerFunc: (event: PdfPageChangeEvent) => void) => Promise<PluginListenerHandle>Listen for page changes while the user scrolls or when {@link PdfViewerPlugin.goToPage} runs.
| Param | Type |
| ------------------ | ------------------------------------------------------------------------------------- |
| eventName | 'pageChange' |
| listenerFunc | (event: PdfPageChangeEvent) => void |
Returns: Promise<PluginListenerHandle>
Since: 8.0.0
addListener('error', ...)
addListener(eventName: 'error', listenerFunc: (event: PdfErrorEvent) => void) => Promise<PluginListenerHandle>Listen for errors while opening or displaying a PDF.
| Param | Type |
| ------------------ | --------------------------------------------------------------------------- |
| eventName | 'error' |
| listenerFunc | (event: PdfErrorEvent) => void |
Returns: Promise<PluginListenerHandle>
Since: 8.0.0
addListener('close', ...)
addListener(eventName: 'close', listenerFunc: (event: PdfCloseEvent) => void) => Promise<PluginListenerHandle>Listen for viewer close (user gesture or {@link PdfViewerPlugin.close}).
| Param | Type |
| ------------------ | --------------------------------------------------------------------------- |
| eventName | 'close' |
| listenerFunc | (event: PdfCloseEvent) => void |
Returns: Promise<PluginListenerHandle>
Since: 8.0.0
addListener('linkTap', ...)
addListener(eventName: 'linkTap', listenerFunc: (event: PdfLinkTapEvent) => void) => Promise<PluginListenerHandle>Listen for taps on links inside the PDF.
| Param | Type |
| ------------------ | ------------------------------------------------------------------------------- |
| eventName | 'linkTap' |
| listenerFunc | (event: PdfLinkTapEvent) => void |
Returns: Promise<PluginListenerHandle>
Since: 8.0.0
Interfaces
OpenPdfResult
Result returned after a PDF successfully opens.
| Prop | Type | Description |
| --------------- | ------------------- | -------------------------------------- |
| pageCount | number | Total number of pages in the document. |
| page | number | Current page, 1-based. |
OpenPdfOptions
Options for {@link PdfViewerPlugin.open}.
| Prop | Type | Description | Default | Since |
| ---------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | ----- |
| source | string | PDF location: file URL, device path, https URL, or base64 (raw or data: URI). | | |
| sourceType | PdfSourceType | Explicit source kind. When omitted: - data: or raw base64 without a scheme => base64 - http/https => url - otherwise => file (treated like a path or file URL; path is an alias on native) | | 8.0.0 |
| headers | Record<string, string> | HTTP headers used when downloading an https url source (for example auth tokens). | | 8.0.0 |
| password | string | Password for encrypted PDFs on iOS and Android. On web the password cannot be injected into the browser viewer; the browser may still prompt. | | 8.0.0 |
| mode | PdfDisplayMode | How to present the viewer. | 'fullscreen' | 8.0.0 |
| elementId | string | DOM element id used when mode is inline. Native code measures this element and places the viewer over it. | | 8.0.0 |
| page | number | Initial page, 1-based. | | 8.0.0 |
| scrollMode | PdfScrollMode | Scroll behavior inside the viewer. | 'continuous' | 8.0.0 |
GoToPageOptions
Options for {@link PdfViewerPlugin.goToPage}.
| Prop | Type | Description |
| ---------- | ------------------- | --------------------- |
| page | number | Target page, 1-based. |
SetZoomOptions
Options for {@link PdfViewerPlugin.setZoom}.
| Prop | Type | Description |
| ----------- | ------------------- | -------------------------------------------------------- |
| scale | number | Zoom multiplier. 1 is the default fit scale on native. |
PluginVersionResult
Plugin version payload from {@link PdfViewerPlugin.getPluginVersion}.
| Prop | Type | Description |
| ------------- | ------------------- | --------------------------------------------------------------------------------------------------- |
| version | string | Version identifier returned by the platform implementation (native on iOS/Android, web on web). |
PluginListenerHandle
| Prop | Type |
| ------------ | ----------------------------------------- |
| remove | () => Promise<void> |
PdfLoadEvent
Payload for the load event.
| Prop | Type | Description |
| --------------- | ------------------- | ---------------------- |
| pageCount | number | Total number of pages. |
| page | number | Current page, 1-based. |
PdfPageChangeEvent
Payload for the pageChange event.
| Prop | Type | Description |
| --------------- | ------------------- | ---------------------- |
| page | number | Current page, 1-based. |
| pageCount | number | Total number of pages. |
PdfErrorEvent
Payload for the error event.
| Prop | Type | Description |
| ------------- | ------------------- | ----------------------------- |
| message | string | Human-readable error message. |
PdfLinkTapEvent
Payload for the linkTap event.
| Prop | Type | Description |
| --------- | ------------------- | ----------------------------------- |
| url | string | Destination URL of the tapped link. |
Type Aliases
PdfSourceType
How the source string should be interpreted.
When omitted, the plugin infers the type from the string shape.
'file' | 'path' | 'url' | 'base64'
Record
Construct a type with a set of properties K of type T
{ [P in K]: T; }
PdfDisplayMode
Presentation mode for the viewer.
fullscreen: covers the app with a native or browser overlay.inline: places the viewer over a DOM element identified byelementId.
'fullscreen' | 'inline'
PdfScrollMode
Page scrolling behavior.
continuous: pages flow vertically as one scrollable document.single: one page at a time.
'continuous' | 'single'
PdfCloseEvent
Payload for the close event (empty object).
Record<string, never>
