Works with any backend npm install Zero dependencies

PDF + video previews in the same lightbox that handles images

The lightbox now auto-detects media kind from the URL / MIME / filename and renders accordingly. PDFs open in a sandboxed iframe pointed at a Blob URL - no extra dependency, no document.com round-trip. Click any PDF or video thumbnail in the queue to open it inline.

Try it: queue a PDF and a video (mp4 / webm). A " Preview" button appears next to each filename. Click - PDFs open in a scrollable inline iframe, videos in an HTML5 player with controls.
API
// Auto-detection from URL / Blob / MIME / filename
MultipleUpload.showLightbox('/files/report.pdf', 'Q3 Report');
MultipleUpload.showLightbox('/clips/demo.mp4', 'Product demo');
MultipleUpload.showLightbox('/img/banner.png', 'Banner');

// Force a specific kind (useful when the URL has no extension)
MultipleUpload.showLightbox(blob, 'Preview', { kind: 'video' });

// Pass a File/Blob directly - object URL is auto-created + revoked on close
MultipleUpload.showLightbox(file, file.name);

// Close programmatically
MultipleUpload.closeLightbox();
What renders for each kind
KindDetectionElementFeatures
image (default)Anything else; PNG/JPG/GIF/WebP/AVIF/SVG<img>object-fit: contain, max 90vw x 80vh
videovideo/* MIME or .mp4 .webm .mov .m4v .ogg .ogv<video controls>playsInline, preload=metadata, auto-pause on close
pdfapplication/pdf MIME or .pdf<iframe>sandbox=allow-same-origin/scripts/popups, referrerpolicy=no-referrer
Memory safety
  • Blob-derived URLs: auto-created via URL.createObjectURL; revoked when the lightbox closes.
  • Video pause-on-close: the <video> element's pause() + src='' + load() sequence releases media resources immediately.
  • Iframe sandbox: PDFs are isolated from your page's JS context - third-party PDFs can't navigate or inject scripts.
Build your own preview button

Most teams want preview ON the queue rows. The taskAdded event fires when a file lands in the queue - perfect hook to inject a preview affordance:

uploader.on('taskAdded', (task) => {
 const row = document.querySelector(`[data-task-id="${task.id}"] .mu-queue-name`);
 if (!row) return;
 const btn = document.createElement('button');
 btn.textContent = '';
 btn.onclick = () => MultipleUpload.showLightbox(task.file, task.fileName);
 row.appendChild(btn);
});