Lumeo

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 />

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:

  1. Explicit Kind parameter (anything other than Auto short-circuits)
  2. Explicit MimeType parameter (most reliable for blob URLs / signed URLs where the extension is hidden)
  3. Optional HEAD request Content-Type — off by default (AutoHead="true" to enable) because many CDNs reject HEAD with 405
  4. URL extension — the last-resort guess from the path segment
sample.svg
sample.svg
README.md
data.csv
Program.cs
/ 0
100%

Force a kind when the URL has no extension (typical for blob / signed URLs).

/ 0
100%

Provide MIME from your backend metadata response — most reliable for opaque URLs.

screenshot.svg
screenshot.svg
README.md
archive.zip

Preview unavailable

This file type cannot be previewed inline.

does-not-exist.csv
sample.svg
sample.svg
sample.svg

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) directly
  • ConfigureRequest="..." — mutate the outgoing HttpRequestMessage per call (typical for Authorization headers)
  • Register HttpClient in DI — picked up automatically (the standard Blazor WASM pattern)

Safety Limits

  • MaxBytes (default 10 MB) — refused upfront via Content-Length when 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 .md never reach the DOM.
  • SVG renders via <img> (not inline) — embedded scripts in SVG can't execute.
  • In-flight fetches are cancelled via CancellationToken when Src changes.

Accessibility

  • Body region wears role="document" with an aria-label derived from the file name or kind.
  • Loading + error states announce via the default Spinner / EmptyState components (both come pre-wired with aria-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.