PDF Viewer

Renders a PDF with search, a thumbnail sidebar, zoom controls, and download.

Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/pdf-viewer.json
Dependencies
PdfViewer is built on react-pdf (which wraps pdf.js). The pdf.js worker is loaded from a CDN by default — no bundler config required.

npm packages

  • react-pdf — Renders PDF pages as canvas + text layers.
Usage
Import the component and pass any PDF URL.
TSImport
import { PdfViewer } from "@/components/ui/pdf-viewer";
TSExample
import { PdfViewer } from "@/components/ui/pdf-viewer";

export function Example() {
  return (
    <PdfViewer
      fileUrl="https://example.com/document.pdf"
      height="auto"
    />
  );
}
Composition
Anatomy of the PdfViewer.
PdfViewer                          (single component — built on react-pdf)
├── fileUrl="…"                    (any direct PDF URL)
├── height={number | string | "auto"}   ("auto" sizes to the document)
├── className="…"                  (extends the outer container)
├── proxy={false}                  (skip /api/pdf-proxy for CORS-ready hosts)
├── onPageChange={(page, canvas) => …}   (page in view + its drawn canvas)
└── markedPages={[3, 14]}          (flag pages in the thumbnail rail)

Built-in chrome:
  • Toolbar — full-text search, page "3 / 30", zoom in / out, download
  • Opens fitted — the page as large as the view allows, width or height,
    whichever comes first; click the % to fit again after zooming
  • Sidebar — clickable thumbnails for every page (click to scroll)
  • Scroll surface — continuous page list, highlights search matches

Only pages near the view are drawn, and the file is read over range
requests, so page one of a 150 MB booklet costs well under a megabyte.
Default
Continuous scroll of all pages with a thumbnail sidebar, full-text search, zoom in/out, and download.
Custom URL
Paste any direct PDF URL into the field — the viewer reloads with the new document.
In a modal
Drop the viewer inside a Dialog/Modal so the document opens in an overlay without leaving the current page.
API Reference
Props exposed by the PdfViewer component.
PropTypeDefaultDescription
fileUrlstring—Direct URL to the PDF file to render.
heightnumber | string | "auto"640Height of the viewer surface. Numbers are treated as px. Pass "auto" to size the container to the first page; add a max-h-* class (e.g. max-h-[70vh]) and the page is fitted inside that cap, so a landscape page gives a short viewer and a tall one stops at the cap.
classNamestring—Extends the outer container classes.
proxybooleantrueRoute cross-origin URLs through the app's /api/pdf-proxy. Pass false when the host sends CORS headers itself (S3, Wasabi) or the app has no proxy route.
onPageChange(page: number, canvas: HTMLCanvasElement | null) => void—Fires when the page in view changes and again when it finishes drawing. canvas is null while it draws; read it right away (e.g. to scan a QR code) — it is discarded once the page scrolls away.
markedPagesreadonly number[]—Pages to flag with a dot in the thumbnail rail, e.g. the ones a checker had something to say about.