The viewer: renders a PDFDocument inside a DOM container and wires its pages, form fields, toolbar, sidebar and tools. It takes a PDFViewerConfig; viewer.config is that configuration resolved over the defaults, with what the license does not cover switched off.
The viewer is on the page when the constructor returns; it is ready — pages laid out, fields and tools wired — a moment later, which whenReady() resolves at and isReady reports. Every member that acts throws INVALID_STATE after destroy(); the getters keep answering their last values. Which license feature each member needs is stated on the member; a member without one needs nothing beyond an open document.
Throws NOT_INITIALIZED before Kernstra.init() has resolved, DOCUMENT_CLOSED for a document already closed, INVALID_ARGUMENT when container is not an element (a ref not yet set), INVALID_STATE when the container already holds a viewer (destroy that one first — a component that re-renders builds one viewer per element, never a second into the same one), and ENGINE_FAILED when the SDK has stopped on an unrecoverable fault (fatal). The viewer is on the page when the constructor returns; it is ready a moment later, which whenReady() resolves at. A loader PDFViewer.showLoadingIndicator put in the container stays over the viewer until you remove it, so "show the loader, open, construct, await viewer.whenReady(), hide" is the whole sequence. If new PDFViewer() throws, the viewer has already undone whatever it had set up; there is nothing to destroy.
Parameter
Type
Description
container
HTMLElement
The element the viewer is rendered into.
document
PDFDocument
An open PDFDocument.
config?
PDFViewerConfig
The viewer configuration; your options over the defaults.
Resolved configuration: your options over the defaults, with what the license does not cover switched off (its tools, and toolbar.print / download). Its tools names every tool: false for one you, the mode or the license switched off, otherwise your options for it or true. Follows the rights of the viewer's document: grows at once when they grow, and narrows only when pages are imported or another document is opened.
Handles for running tools — see viewer.tools.editText. A handle throws SDKErrorINVALID_STATE, with instructions, when its tool is not running, rather than failing silently.
true from the first change on — a tool's, a page's, a field filled in or signed, the document API's, an undo — until the document is exported whole by an exporter from createExporter() (the toolbar's Download; download(), getBlob(), getArrayBuffer(), getBase64(), uploadTo() without pages) or markSaved() is called. A change made while an export ran stays unsaved; an undo back to the saved state still counts. documentChanged reports every change of it; nothing reports it going back to false. The export is the "save": a host that uploads the bytes keeps its own flag for an upload that failed, or a "leave without saving?" guard lets the user go after one — see Saving as the user works.
Returnsboolean
TypeScript
window.addEventListener('beforeunload', (e) => {
if (viewer.hasUnsavedChanges) e.preventDefault();
});
The active tool's name — 'selectText' at rest by default, from the moment the viewer goes back to it — or null when no tool is active. A property, read like viewer.scale.
One step, as the toolbar's buttons and ⌘/Ctrl + do: to the next preset of navigation.zoomPresets above the current scale, then by steps up to navigation.maxZoom. Leaves a fit mode.
One step, as the toolbar's buttons and ⌘/Ctrl − do: to the next preset of navigation.zoomPresets below the current scale, then by steps down to navigation.minZoom. Leaves a fit mode.
Activate a tool (again: put it away, back to the resting tool). Edit Text left with edits pending writes them first; a refused write keeps it, and the promise resolves with it still active. Needs the tool's license feature; refused for a tool the license does not cover.
Parameter
Type
Description
tool
ToolName
One of the 26 names of TOOL_NAMES, in the toolbar's order. Two of them are panels rather than tools: 'search' and 'managePages' open their panel and resolve, and activeTool stays what it was — openPanel('search') / openPanel('pages') are the same action by their own name. The exported PANEL_TOOL_NAMES names those two, so a host that marks its buttons pressed from activeTool or toolChanged need not hard-code them.
ReturnsPromise<void>
INVALID_ARGUMENT for a name that is no tool or a tool that is off — see isToolEnabled.
FEATURE_NOT_LICENSED for one the license does not cover.
PERMISSION_DENIED for one the document's permissions forbid — see toolBlockedReason.
UNKNOWN_ERROR (the cause as its cause; or the tool's own SDKError) for a tool that could not start — nothing of it stays, and the viewer goes back to the resting tool.
INVALID_STATE after destroy().
TypeScript
await viewer.activateTool('highlight');
await viewer.activateTool('highlight'); // again: back to the resting tool
Put the active tool away and go back to the resting tool (defaultTool, Select by default); with the resting tool active, put down what is selected — an annotation picked up, the text Select selected. Edit Text with edits pending writes them first, as Done does, and the promise resolves once the tool is away; a refused write keeps the tool (activeTool tells). With nothing pending the tool is away before the call returns.
Whether a tool may run: covered by the license, not false in tools, and offered by the mode (Select, Pan and Search in every mode, Sign in FORM_FILL and FULL, the rest in FULL only). toolbar.groups does not affect it. Mirror it in your own chrome instead of duplicating the rule.
Why the open document forbids a tool — { reason, message }: reason is 'permission' (the document's permissions), 'certified' (its certification) or 'downloading' (it edits, and the document's bytes are still arriving), message the words in the viewer's language ("This document does not allow comments") — or null when it allows it. A tool it forbids is still offered, grayed out with the message. A host drawing its own chrome shows the same, and branches on reason.
Parameter
Type
Description
tool
ToolName
The tool to ask about.
ReturnsToolBlockedReason | null{ reason, message }, or null when the document allows it (and on a destroyed viewer).
Save current document state for undo (called automatically after committed edits). Skipped, with an error event, while a progressively-loaded document is still downloading — so undo has a gap until whenFullyLoaded() resolves. A change whose undo step could not be recorded (an error with EXPORT_FAILED) still counts: hasUnsavedChanges turns true and documentChanged reports it. A change made through the document API while Edit Text has unwritten edits writes those edits first, then reloads; if they cannot be written, the viewer reports INVALID_STATE on error and the edits are lost.
Restore previous document state. Edit Text edits pending are written first, as one step, and that step is what this undo backs out; nothing is undone when the write is refused.
Tells the viewer the document as it stands is saved: hasUnsavedChanges is false until the next change. Called for you when the document is exported whole; call it yourself after saving through doc.save() or your own path.
Open the search panel and run a query across all pages. Results are shown in the panel, not returned: it is a UI action. For matches as data, use doc.text.search(). Needs the extract feature: its highlights and count say where the words are (the search panel the user types in needs no feature).
Parameter
Type
Description
query
string
The words to look for.
ReturnsPromise<void> Resolves once the search has run.
Scroll a field into view (any page) and focus its editor. Values are read and set through doc.forms, with or without a viewer. While this viewer is open they go through its fields: shown at once, on its undo stack, in its export, and formFieldChanged fires once per applied field.
Open the Comments panel on the comment with that id (a reply's or a status's id opens its comment): its card chosen, its mark scrolled to and outlined.
Parameter
Type
Description
id
string
A comment's id; a reply's or a status's id opens its comment.
ReturnsPromise<boolean>false if no comment has it or the panel is not offered.
What the user may do to a comment by the panel's rules — { reply, setStatus, edit, delete }; null when no comment has that id (none, or a link, form field, pop-up or hidden annotation).
Parameter
Type
Description
id
string
The comment's id.
ReturnsPromise<CommentPermissions | null>{ reply, setStatus, edit, delete }, each a boolean.
INVALID_STATE after destroy().
TypeScript
const may = await viewer.commentPermissions(id);
deleteButton.hidden = may?.delete !== true;
pageToClient<TextendsRect | Point>(value: T, pageIndex: number): T | null
A point or rectangle of a page, in page space, as it lies in the viewer now: CSS pixels from the container's top-left corner at the current zoom, scroll and rotation (a Rect comes back with its top-left corner as x, y, as the DOM measures). Convert again after zoomChanged, a scroll or a resize. Page space and the geometry helpers are described under Helpers.
Parameter
Type
Description
value
Rect | Point
A point or rectangle in page space.
pageIndex
number
Zero-based page index.
ReturnsRect | Point | nullnull before the page is laid out, or on a destroyed viewer.
INVALID_ARGUMENT for a page index the document has not, or a value that is neither a Point nor a Rect of finite numbers.
A PDFExporter wired to this viewer's form values and signatures. Its defaults are the viewer's export option; config overrides them. Obtain the exporter here rather than with new PDFExporter(document): it carries what the viewer holds and reports exportStarted / exportCompleted on the viewer, and an export of the whole document clears hasUnsavedChanges the moment the bytes leave the viewer — whether your upload of them succeeds is yours to track (see Saving as the user works).
Parameter
Type
Description
config?
ExportConfig
Overrides the viewer's export option for this exporter.
Ask for pages and annotations (or take them from options), render at 300 DPI (within performance.maxRenderPixels) with progress, and open the browser print dialog. Needs the print feature.
Parameter
Type
Description
options?
PrintOptions
{ pages?: number[]; annotations?: boolean } — the pages to print (zero-based; every page when omitted) and whether annotations are printed (true when omitted). Without it the viewer asks for pages and annotations.
ReturnsPromise<void> Resolves when the browser reports the print dialog closed (afterprint), or after a minute where it never does.
INVALID_ARGUMENT for a pages list that is empty or names a page the document has not.
FEATURE_NOT_LICENSED without the print feature.
PERMISSION_DENIED when the document forbids printing.
Subscribe to a typed event. Document lifecycle events (initialized, licenseChanged, documentLoaded, documentClosed) are global and fire on Kernstra.events, not here; a handler registered on the wrong emitter never runs and never warns — see EventEmitter.
Resolves once the viewer is ready: pages laid out, form fields and tools wired, the pages in view queued to paint — the moment to remove a loading indicator of your own. A progressive document's later pages still arrive after it (doc.whenFullyLoaded() says when every byte has).
ReturnsPromise<void>
ABORTED if destroy() comes first.
PAGE_ERROR when the file's fields or pages cannot be wired (the viewer stands; the error event reports it too).
Removes everything the viewer added to the page: its DOM, every document- and window-level listener, observers, timers, the render worker, its tools, and any of its dialogs or popovers still open (a pending print() resolves without printing). Safe to call twice. A shape or annotation still selected goes back into the document where it was. With the last viewer on the page it also removes the shared stylesheets. The Image tool's recent images, saved signatures and user stamps stay for the page session, for the next viewer.
It does not close the underlying PDFDocument — call document.close() yourself, before or after, or you leak its memory. After it, every member that acts — goToPage(), setScale(), activateTool(), print(), search(), openPanel(), undo(), createExporter() and the rest — throws INVALID_STATE rather than doing nothing; the getters keep answering their last values. A stale handler that still reaches the viewer is a bug this makes visible.
Show a loading spinner before a viewer exists. Involves no document. A loader put in the container stays over the viewer until you remove it: show the loader, open, construct, await viewer.whenReady(), hide.
Parameter
Type
Description
container
HTMLElement
The element the viewer will be rendered into.
options?
{ loader?: LoaderConfig; locale?: LocaleConfig }
options.loader is a LoaderConfig and options.locale a LocaleConfig — pass the ones you give the viewer.