Smart Embed
Learn how to embed PreviewFile preview links in different scenarios with automatic adaptation
PreviewFile's /p/xxx preview links support intelligent request source detection, automatically returning the most appropriate content format based on the usage scenario.
Core Features
One preview link, multiple use cases:
- 🖼️ In
<img>tags: Returns image or file type icon - 🎬 In
<video>tags: Returns video or placeholder icon - 🎵 In
<audio>tags: Returns audio or placeholder icon - 📺 In
<iframe>tags: Returns embedded viewer (PDF/video/image) - 🌐 Direct browser access: Displays complete preview interface
How It Works
PreviewFile detects the HTTP request headers (sec-fetch-dest, accept) to identify the request source, then intelligently returns content in the corresponding format.
Usage Scenarios
1. IMG Tag - Thumbnails and Icons
Quickly display file previews in Markdown, emails, and documents:
<img src="https://previewfile.dev/p/abc123" alt="File Preview">Behavior:
- ✅ Image files → Display actual image
- ✅ PDF files → Display 📄 PDF icon
- ✅ Video files → Display 🎬 VIDEO icon
- ✅ Document files → Display 📝 DOC icon
- ✅ Expired/not found → Display ⏰ error icon
Supported Icon Types:
| File Type | Icon | Example Extensions |
|---|---|---|
| Image | 🖼️ | jpg, png, gif, webp |
| Video | 🎬 | mp4, mov, avi, mkv |
| Audio | 🎵 | mp3, wav, aac, flac |
| 📄 | ||
| Document | 📝 | doc, docx, txt, md |
| Spreadsheet | 📊 | xls, xlsx, csv |
| Presentation | 📽️ | ppt, pptx, key |
| Archive | 📦 | zip, rar, 7z, tar |
| Code | 💻 | js, ts, py, java |
| Unknown | 📎 | other types |
Real-world Examples:
<!-- Markdown -->

<!-- HTML -->
<img src="https://previewfile.dev/p/contract-v2" width="200">
<!-- React -->
<Image src="https://previewfile.dev/p/design-mockup" alt="Design" />2. VIDEO Tag - Video Playback
Embed videos directly in web pages:
<video src="https://previewfile.dev/p/demo-video" controls></video>Behavior:
- ✅ Video files (mp4/mov/webm) → Stream video directly
- ✅ Non-video files → Display file type icon
- ✅ Expired → Return 410 Gone
Advanced Configuration:
<video
src="https://previewfile.dev/p/tutorial"
controls
autoplay
muted
loop
width="800"
height="450"
poster="https://example.com/thumbnail.jpg"
>
Your browser does not support video playback.
</video>3. AUDIO Tag - Audio Playback
Embed audio files (podcasts, music, recordings):
<audio src="https://previewfile.dev/p/podcast-ep1" controls></audio>Behavior:
- ✅ Audio files (mp3/wav/aac) → Stream audio directly
- ✅ Non-audio files → Display file type icon
Custom Player:
<audio
src="https://previewfile.dev/p/meeting-recording"
controls
preload="metadata"
>
Your browser does not support audio playback.
</audio>4. IFRAME - Embedded Viewer
Display files in an embedded viewer (PDF, videos, images):
<iframe
src="https://previewfile.dev/p/report-q4"
width="100%"
height="600"
frameborder="0"
allowfullscreen
></iframe>Supported File Types:
- ✅ PDF: Native browser PDF viewer
- ✅ Videos: HTML5 video player
- ✅ Images: Full-screen image display
- ❌ Other types: Display "Not supported" message
Responsive 16:9 Container:
<div style="position: relative; padding-bottom: 56.25%; height: 0;">
<iframe
src="https://previewfile.dev/p/presentation"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
frameborder="0"
allowfullscreen
></iframe>
</div>5. Direct Browser Access - Full Preview Page
When users click the link or access it directly via browser:
<a href="https://previewfile.dev/p/abc123" target="_blank">
View File
</a>Features:
- ✅ Display file metadata (name, size, type)
- ✅ Show access statistics (views, remaining time)
- ✅ Security indicators (watermark, download restrictions)
- ✅ Preview area (images/videos/PDFs)
- ✅ Download button (if enabled)
- ✅ Embed code examples
Advanced Usage
1. Lazy Loading Images
Improve page load performance:
<img
src="https://previewfile.dev/p/large-image"
loading="lazy"
alt="Large Image"
/>2. Error Handling
Provide fallback for expired or missing files:
<img
src="https://previewfile.dev/p/abc123"
onerror="this.src='https://placehold.co/600x400?text=File+Expired'"
alt="Preview"
/>3. Dynamic Embedding with JavaScript
// Dynamic image
const img = document.createElement('img');
img.src = 'https://previewfile.dev/p/dynamic-file';
img.alt = 'Dynamic Preview';
document.getElementById('preview-container').appendChild(img);
// Dynamic video
const video = document.createElement('video');
video.src = 'https://previewfile.dev/p/video-clip';
video.controls = true;
document.getElementById('video-container').appendChild(video);4. Responsive CSS
Ensure embedded content adapts to all screen sizes:
img, video, audio, iframe {
max-width: 100%;
height: auto;
}
.embed-container {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
height: 0;
overflow: hidden;
}
.embed-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}5. Localization
You can force a specific language for the preview interface by appending the lang or locale query parameter.
Supported Languages:
en: Englishzh-CN: Simplified Chinesezh-TW: Traditional Chineseja: Japanese
Example:
<!-- Force English Interface -->
<iframe src="https://previewfile.dev/p/abc123?lang=en"></iframe>
<!-- Force Japanese Interface -->
<a href="https://previewfile.dev/p/abc123?lang=ja">Link</a>This ensures error messages and UI elements are displayed in the desired language regardless of the user's browser settings.
Social Media Integration
Discord / Slack
Simply paste the link—rich previews are automatic:
https://previewfile.dev/p/screenshotGitHub README

<!-- Or with HTML for sizing -->
<img src="https://previewfile.dev/p/architecture" width="800" />Notion
Use Markdown image syntax or /embed block:
Email (HTML)
<a href="https://previewfile.dev/p/invoice-2024">
<img src="https://previewfile.dev/p/invoice-2024" alt="Invoice" width="600" />
</a>Security Policy Impact
Different access methods respect security policies differently:
| Policy | Browser Access | HTML Embed |
|---|---|---|
| TTL Expired | Show "Preview Expired" message | Return error icon or 410 Gone |
| One-Time Link | Show "Link Used" message | Return 403 Forbidden |
| Download Disabled | Right-click disabled in UI | Normal display (browser controls) |
| Watermark | Display semi-transparent watermark | Depends on file type |
⚠️ Note: While intelligent routing returns different content based on request type, it cannot completely prevent file downloads (browser native functionality).
Access Tracking
All access methods (browser and HTML embed) will:
- ✅ Increment
viewCount - ✅ Check TTL and one-time link policies
- ✅ Record in database
This allows you to track how your files are being accessed across different platforms.
Testing Embed Functionality
1. Using Test Page
Visit: http://localhost:3707/test-embed.html
Provides a complete interactive testing interface including:
- Section 1: IMG Tag Test
- Section 2: VIDEO Tag Test
- Section 3: AUDIO Tag Test
- Section 4: IFRAME Tag Test
- Section 5: Browser Direct Access
- Section 6: Example Usage
2. Using cURL
# Browser access (returns React UI)
curl -H "sec-fetch-dest: document" https://previewfile.dev/p/abc123
# IMG tag access (returns image or icon)
curl -H "sec-fetch-dest: image" https://previewfile.dev/p/abc123
# VIDEO tag access (returns video or icon)
curl -H "sec-fetch-dest: video" https://previewfile.dev/p/abc123
# AUDIO tag access (returns audio or icon)
curl -H "sec-fetch-dest: audio" https://previewfile.dev/p/abc123
# IFRAME access (returns HTML player)
curl -H "sec-fetch-dest: iframe" https://previewfile.dev/p/abc1233. Using Browser DevTools
- Open Network panel
- Access
/p/abc123 - Check
sec-fetch-destvalue in request headers - Observe returned content type
FAQ
Q1: Why does a single route support multiple functions?
A: Through Next.js middleware detecting HTTP request headers (sec-fetch-dest), the system automatically identifies whether it's browser access or HTML tag embedding, then returns appropriate content.
Q2: Will embedded links expire?
A: Yes, they follow the preview session's TTL settings. After expiration, browser access shows "Preview Expired" message, while HTML tag embeds show error icons or return 410 Gone.
Q3: Can I embed private files?
A: Yes. The system generates S3 presigned URLs with expiration time (typically 1 hour or remaining TTL, whichever is smaller).
Q4: What happens if an IMG tag accesses a non-image file?
A: The system returns an SVG file type icon (200x200px) displaying the file extension and corresponding emoji icon.
Q5: What happens if VIDEO/AUDIO tags access non-video/audio files?
A: Similarly returns an SVG file type icon, ensuring the page won't error due to file type mismatch.
Q6: Which file types does IFRAME embedding support?
A: Currently supports PDF, videos (MP4/MOV/AVI, etc.), and images (JPG/PNG/GIF, etc.). Unsupported file types show "File type not supported" message.
Q7: How do I prevent embed link abuse?
A: Use a combination of strategies:
- Set short TTL (e.g., 30 minutes)
- Enable one-time links (
oneTime: true) - Monitor
viewCount, manually invalidate when threshold exceeded - Limit access frequency at S3 layer
Best Practices
1. Use Unified /p/[shortUrl]
- No need to distinguish between browser and embed access
- System automatically identifies and returns appropriate content
- Simplifies sharing and integration
2. Set Reasonable TTL
- Temporary sharing: 30-60 minutes
- Short-term use: 1-24 hours
- Long-term embedding: Use with caution, consider CDN instead
3. Handle Expiration
<img
src="https://previewfile.dev/p/abc123"
onerror="this.src='https://placehold.co/600x400?text=File+Expired'"
alt="Preview"
/>4. Use Responsive Design
img, video, audio, iframe {
max-width: 100%;
height: auto;
}5. Leverage File Type Icon Fallback
- Even if file type doesn't match, a friendly icon is displayed
- No need for additional error handling logic
- Improves user experience
Next Steps
- See API Documentation to learn about programmatically creating preview links
- Read Security Documentation for more protection measures
- Visit Dashboard to manage all preview links