Lumeo

PDF Viewer

Inline PDF document viewer powered by Mozilla pdf.js. Renders multi-page documents on a canvas with page navigation, zoom controls, optional text search, and a one-click download shortcut. No npm build step or API key required.

Installation

dotnet add package Lumeo.PdfViewer

One-time app setup (AddLumeo(), CSS & JS) is covered in the installation guide.

Usage

@using Lumeo

<PdfViewer />

When to Use

  • Embedding contracts, invoices, or reports inline in a Blazor page without leaving the app
  • Document preview surfaces where the browser's built-in viewer behaves inconsistently across platforms
  • Read-only flows that benefit from page navigation, zoom, and full-text search (e.g. audit trails, e-signatures)
  • Dashboards that surface generated PDF reports alongside live data
  • Admin panels that need to display uploaded user documents with a controlled, branded UI
/ 0
100%

Default yellow

/ 0
100%

HighlightColor="orange"

/ 0
100%

HighlightColor="hsl(200 90% 50%)"

/ 0
100%
/ 0
100%
/ 0
100%
/ 0
150%

Page 1 of 1 · zoom 100%

/ 0
100%

Self-hosting pdf.js

By default the viewer lazy-loads pdf.js + its worker from jsDelivr the first time a PdfViewer mounts. That's the right tradeoff for low-traffic apps and demos, but it doesn't work behind a strict CSP, on an air-gapped intranet, or in compliance scenarios where every third-party script call is a no-go.

The Lumeo CLI ships a one-shot installer that vendors pdf.js into wwwroot/lib/lumeo-vendor/ and wires up window.lumeoCdn so the runtime loads from your own origin instead of the CDN:

bash
# 1. Install the Lumeo CLI as a global dotnet tool
$ dotnet tool install -g Lumeo.Cli

# 2. Vendor pdf.js into wwwroot/lib/lumeo-vendor/ and write the bootstrap
$ lumeo deps install --lib pdfjs --write-bootstrap

# 3. Include the bootstrap before _content/Lumeo.PdfViewer/js/* in index.html
#    <script src="js/lumeo-cdn-init.js"></script>

See CDN dependencies for the full list of self-hostable libraries and the window.lumeoCdn override surface. For more granular control (custom URL, integrity hash, alternative CDN) you can set window.lumeoCdn = { pdfJs: "/my/cdn/pdf.min.mjs", pdfJsWorker: "/my/cdn/pdf.worker.min.mjs" }; before the first PdfViewer mounts.

API Reference

PdfViewer

Prop Type Default Description
Src string? null PDF URL or data: URI. Marked [EditorRequired] — must be provided. Changing this value reloads the document.
Page int 1 1-based current page index. Two-way bindable via @bind-Page.
PageChanged EventCallback<int> Fires with the new page number whenever the user navigates (toolbar buttons, keyboard, or direct input).
Zoom double 1.0 Render scale clamped to [0.5, 4.0]. Two-way bindable via @bind-Zoom. Steps of 0.25 per toolbar click.
ZoomChanged EventCallback<double> Fires with the new scale factor whenever the user changes zoom.
ShowToolbar bool true Show the entire toolbar row. Set false for a chromeless embed driven by parent state.
ShowPageNav bool true Show the prev / next buttons and editable page number input in the toolbar.
ShowZoomControls bool true Show the ± zoom buttons and percentage label in the toolbar.
ShowDownload bool true Show the download anchor linking to Src. Hide when the document should not be extractable.
ShowSearch bool false Show the full-text search input. Returns the total match count across all pages.
HighlightColor string "yellow" CSS color string for search match highlights. Accepts any valid CSS color: named (yellow), hex (#facc15), rgb/hsl. Active matches render at 70% opacity; inactive at 45%, mixed against transparent via color-mix.
OnLoaded EventCallback<int> Fires once with the total page count after the PDF finishes loading. Use to initialise parent state.
OnPageChanged EventCallback<int> Non-binding alternative to PageChanged. Useful when you only need a side-effect callback without two-way binding.
OnError EventCallback<string> Fires when the PDF fails to load or render (CDN unreachable, malformed PDF, worker init failure). Receives the exception message. The built-in EmptyState fallback still renders inside the viewer.
Class string? null Extra CSS classes applied to the root container. Use to set a fixed height (e.g. h-[600px]) or override border radius.

Keyboard shortcuts

Focus the canvas area (click once or Tab to it) then use:

Key Action
PageDown / ArrowRight Next page
PageUp / ArrowLeft Previous page
+ / = Zoom in (+25%)
- / _ Zoom out (−25%)
Accessibility. The canvas wrapper renders role="document" with aria-label="PDF document" and tabindex="0" so it receives keyboard focus. The loading overlay uses role="status" with aria-live="polite". Search match counts are announced via aria-live.