File Viewer
Universal preview surface — detects the file type from MIME / extension and renders inline: PDF, images, video, audio, Markdown, source code, JSON, CSV, and plain text. Unknown types fall back to a download CTA. One component replaces a stack of bespoke per-type renderers.
Installation
dotnet add package Lumeo
One-time app setup (AddLumeo(), CSS & JS) is covered in the
installation guide.
Usage
@using Lumeo <FileViewer />
Lumeo.FileViewer — install it alongside the core Lumeo
package. It transitively pulls Lumeo.PdfViewer
(for the PDF kind) and Lumeo.CodeEditor (for the Code / JSON
kinds), so a single install covers every supported preview.
When to Use
- Document or attachment lists where each row links to a heterogeneous file (PDF report, screenshot, CSV export, README)
- File managers / DMS surfaces that need a quick preview pane next to the tree
- Audit / compliance flows where the user has to inspect the actual content before approving an action
- Ticketing systems where customers attach mixed-format evidence
- Anywhere consumers would otherwise build a switch over Pdf / Image / Video / Markdown viewers by hand
How Detection Works
Resolution runs in this order — each step wins over the next:
- Explicit
Kindparameter (anything other thanAutoshort-circuits) - Explicit
MimeTypeparameter (most reliable for blob URLs / signed URLs where the extension is hidden) - Optional
HEADrequestContent-Type— off by default (AutoHead="true"to enable) because many CDNs reject HEAD with 405 - URL extension — the last-resort guess from the path segment
Auth-Aware Fetching
Text-based kinds (Markdown, Code, JSON, CSV, Text) are fetched via HttpClient.
For signed-but-not-presigned URLs you have three knobs:
HttpClient="..."— pass a pre-configured client (with handlers attached) directlyConfigureRequest="..."— mutate the outgoingHttpRequestMessageper call (typical forAuthorizationheaders)- Register
HttpClientin DI — picked up automatically (the standard Blazor WASM pattern)
Safety Limits
MaxBytes(default 10 MB) — refused upfront viaContent-Lengthwhen known, truncated mid-stream otherwise. No 100 MB OOMs.MaxCsvRows(default 1000) — CSV parser stops after this many rows and adds a truncation notice.- Markdown is rendered with
.DisableHtml()— raw<script>/<iframe>in user-supplied.mdnever reach the DOM. - SVG renders via
<img>(not inline) — embedded scripts in SVG can't execute. - In-flight fetches are cancelled via
CancellationTokenwhenSrcchanges.
Accessibility
- Body region wears
role="document"with anaria-labelderived from the file name or kind. - Loading + error states announce via the default
Spinner/EmptyStatecomponents (both come pre-wired witharia-live). - Video / audio kinds use native browser controls with their built-in keyboard handling.
- The download anchor is keyboard-reachable with a visible focus ring on the toolbar.