PdfDocument.preview replaces a target element with the package preview.
const pdf = await renderPdf(document.querySelector("#report")!);
const target = document.querySelector<HTMLElement>("#pdf-preview");
if (!target) throw new Error("Preview target not found");
const preview = await pdf.preview(target, {
initialScale: "fit-width",
showToolbar: true,
theme: "system",
});The preview uses an isolated Shadow DOM subtree and canvas pages. It does not use the browser PDF plugin.
Preview options
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
showToolbar | boolean | No | true | Whether to show the page navigation and zoom toolbar. Defaults to `true`. |
padding | number | No | 28, or 16 on narrow screens | Padding around the rendered pages in CSS pixels. Defaults to `28`, or `16` on narrow screens. |
initialScale | number | "fit-width" | No | fit-width | Initial zoom or automatic fit. Defaults to `fit-width`. |
minScale | number | No | 0 | Lowest permitted zoom. Defaults to `0.25` and is never below `0.1`. |
maxScale | number | No | 3 and is never below minScale | Highest permitted zoom. Defaults to `3` and is never below `minScale`. |
zoomStep | number | No | 0 | Zoom-button increment. Defaults to `0.25` and is never below `0.05`. |
maxPixelRatio | number | No | 2 | Device-pixel-ratio cap used for page canvases. Defaults to `2`. |
ariaLabel | string | No | PDF preview | Accessible label for the preview region. Defaults to `PDF preview`. |
theme | PdfPreviewTheme | No | system and follows the browser preference | Preview-control theme. Defaults to `system` and follows the browser preference. |
onProgress | (completedPages: number, totalPages: number) => void | No | None | Called after each page canvas completes rendering. |
onPageChange | (currentPage: number, totalPages: number) => void | No | None | Called once after initial loading and whenever the 1-based current page changes. |
The toolbar contains previous and next page controls, page status, and zoom controls. The page area is keyboard focusable. Set ariaLabel when the surrounding context needs a more specific name.
Navigate between pages
currentPage is 1-based and stays synchronized with toolbar navigation and manual scrolling. goToPage rounds the requested page and clamps it to the document range.
const previousButton = document.querySelector<HTMLButtonElement>("#previous-page")!;
const nextButton = document.querySelector<HTMLButtonElement>("#next-page")!;
const pageStatus = document.querySelector<HTMLOutputElement>("#page-status")!;
const preview = await pdf.preview(target, {
onPageChange(currentPage, totalPages) {
pageStatus.value = `Page ${currentPage} of ${totalPages}`;
previousButton.disabled = currentPage === 1;
nextButton.disabled = currentPage === totalPages;
},
});
previousButton.addEventListener("click", () => preview.previousPage());
nextButton.addEventListener("click", () => preview.nextPage());
preview.goToPage(3);
console.log(preview.currentPage);onPageChange runs after the initial preview loads and whenever the current page changes.
Change scale or theme
await preview.setScale(1.25);
await preview.fitToWidth();
preview.setTheme("dark");Dispose in order
preview.dispose();
pdf.dispose();Disposing the document also disposes previews it still owns. Separate preview disposal is useful when you close the viewer but keep the PDF bytes.