D
DreamLake

Preview

Recipes

Practical patterns for wiring <FilePreview> into real apps.

Auth — custom fetcher with Authorization header

Pre-signed URLs are the cleanest way to ship private files (no auth header needed), but when an API gateway in front of S3 demands a Bearer token, pass a fetcher that injects it:

import { FilePreview } from '@vuer-ai/vuer-m3u/preview'
 
function authFetcher(url: string, init?: RequestInit) {
  return fetch(url, {
    ...init,
    headers: {
      ...(init?.headers ?? {}),
      Authorization: `Bearer ${getToken()}`,
    },
  })
}
 
<FilePreview url={url} fetcher={authFetcher} />

The fetcher is called for every request the previewer makes — text fetches, NPY two-stage Range, MCAP footer reads, the lot. It does not wrap native <img> / <video> requests; for those, use a service worker or pre-signed URLs.

DreamLake metadata pass-through — skip the probe

DreamLake's listing API already returns size and contentType for every file in an episode. Pass these through directly instead of forcing a HEAD round-trip:

import { FilePreview } from '@vuer-ai/vuer-m3u/preview'
 
function FileCard({ file }: { file: EpisodeFile }) {
  return (
    <FilePreview
      url={file.url}
      filename={file.name}
      size={file.size}
      contentType={file.contentType}
    />
  )
}

With size set, the image hard-limit check runs before any fetch. With contentType set, kind resolution falls through to MIME if the extension is ambiguous (e.g. .dat). The default probe='never' means no HEAD request fires.

If you have a mixed source where some files come with metadata and others don't, opt into auto-probe:

<FilePreview url={url} probe="auto" />

probe="auto" only fires HEAD when both size and contentType are missing — this preserves the metadata-fast-path while gracefully handling unknown URLs.

File switcher in a panel

A common shape: list of files on the left, preview pane on the right, click a row to swap the URL. The switcher below stages this pattern with a <select> for compactness.

Loading demo...
import { useState } from 'react'
import { FilePreview } from '@vuer-ai/vuer-m3u/preview'

export function MyComponent() {
  const [url, setUrl] = useState('/files/README.md')
  return (
    <>
      <select value={url} onChange={(e) => setUrl(e.target.value)}>
        <option value="/files/README.md">README.md</option>
        <option value="/files/data.csv">data.csv</option>
      </select>
      <FilePreview url={url} />
    </>
  )
}

A few things worth calling out:

  • <FilePreview> is keyed by url — when url changes, internal state resets. There is no need to remount manually.
  • Lazy chunks load on first use, then cache — flipping from CSV → JSONL → CSV downloads each previewer once.
  • Errors are isolated per preview — a 404 on one URL does not poison the next one.
  • The header bar persists for every kind, including unsupported and error states, so the download button is always available.

Cross-links