Base64 PDF Embedding — Inline PDFs in HTML, JSON APIs, and Email
Embed PDF files as Base64 strings in HTML data URIs, JSON API responses, and email attachments. Learn when Base64 embedding makes sense, the size overhead, and alternatives...
Use the tool
Base64 Encoder / Decoder
Encode and decode Base64 strings and files. Client-side, safe for sensitive data.
Base64-embedding PDFs avoids separate HTTP requests for inline display. The 33% size overhead is acceptable for small documents but problematic for large files.
Encode and decode Base64 with the base64 decoder and encoder.
Embed PDF in HTML with data URI
<!-- Inline PDF viewer using data URI -->
<iframe
src="data:application/pdf;base64,JVBERi0xLjQK..."
width="100%"
height="600px"
type="application/pdf"
>
<p>Your browser doesn't support embedded PDFs.</p>
</iframe>
<!-- Alternative: object tag -->
<object
data="data:application/pdf;base64,JVBERi0xLjQK..."
type="application/pdf"
width="100%"
height="600px"
>
<embed src="data:application/pdf;base64,JVBERi0xLjQK..." type="application/pdf">
</object>
Browser support: Chrome and Firefox support PDF data URIs in iframes. Safari requires a direct URL for <iframe> PDFs — use a blob URL instead.
Node.js: read PDF and create data URI
import { readFileSync } from 'fs';
function pdfToDataURI(filePath) {
const pdf = readFileSync(filePath);
const base64 = pdf.toString('base64');
return `data:application/pdf;base64,${base64}`;
}
// For small reports:
const dataURI = pdfToDataURI('report.pdf');
// Pass to HTML template or JSON response
// Size check: 1MB PDF → ~1.37MB Base64 (33% overhead)
const stats = require('fs').statSync('report.pdf');
console.log(`PDF: ${(stats.size / 1024).toFixed(1)} KB`);
console.log(`Base64: ${(dataURI.length / 1024).toFixed(1)} KB`);
Blob URL approach (browser, avoids Safari issues)
// Browser: convert base64 to blob URL for better compatibility
function base64ToBlobURL(base64, mimeType = 'application/pdf') {
const bytes = atob(base64);
const buffer = new Uint8Array(bytes.length);
for (let i = 0; i < bytes.length; i++) {
buffer[i] = bytes.charCodeAt(i);
}
const blob = new Blob([buffer], { type: mimeType });
return URL.createObjectURL(blob);
}
async function showPDF(base64PDF) {
const blobURL = base64ToBlobURL(base64PDF);
const iframe = document.getElementById('pdf-viewer');
iframe.src = blobURL;
// Revoke URL when done to free memory:
iframe.onload = () => {
// Keep the URL alive while the PDF is shown
// Revoke when navigating away:
};
window.addEventListener('beforeunload', () => URL.revokeObjectURL(blobURL));
}
JSON API: include PDF in response
// Express: include PDF in JSON response (small reports only)
app.get('/api/invoice/:id', async (req, res) => {
const invoice = await generateInvoicePDF(req.params.id);
if (invoice.size > 1024 * 1024) {
// Large PDF: return a URL instead of embedding
const url = await uploadToS3(invoice);
return res.json({ downloadUrl: url, expiresIn: 3600 });
}
const base64 = invoice.toString('base64');
res.json({
invoiceId: req.params.id,
filename: `invoice-${req.params.id}.pdf`,
contentType: 'application/pdf',
data: base64,
size: invoice.size,
});
});
Email attachment (MIME multipart)
import nodemailer from 'nodemailer'; // npm install nodemailer
async function sendEmailWithPDF(to, subject, pdfBuffer) {
const transporter = nodemailer.createTransport({ /* config */ });
await transporter.sendMail({
from: 'sender@example.com',
to,
subject,
text: 'Please find your invoice attached.',
attachments: [
{
filename: 'invoice.pdf',
content: pdfBuffer, // Buffer — nodemailer handles Base64 encoding
contentType: 'application/pdf',
},
],
});
}
// Or with base64 string:
await transporter.sendMail({
attachments: [{
filename: 'report.pdf',
encoding: 'base64',
content: base64String,
}],
});
When to use Base64 vs presigned URL
| Situation | Use |
|---|---|
| PDF < 500KB, needs to be in JSON response | Base64 |
| PDF > 1MB | Presigned S3/GCS URL |
| Real-time generated PDF, one-time use | Blob URL |
| Email attachment | Base64 (MIME standard) |
| Long-term storage / CDN delivery | Storage URL |
| PDF that changes per user | On-demand generation + signed URL |
Related tools
- Base64 Encoder/Decoder — encode/decode Base64
- Image Compressor — compress images before Base64 embedding
- URL Encoder — encode data URIs safely
Related posts
- Base64: How It Actually Works Under the Hood — Base64 is everywhere — in JWTs, data URLs, email attachments. This is the byte-l…
- When You Should NOT Use Base64 Encoding — Base64 is the duct tape of the web — and like real duct tape, it's used in place…
- Base64 Encoding on the Command Line — Linux, macOS, and Windows — Encode and decode Base64 on the command line using base64, openssl, and PowerShe…
- Base64 Data URLs — Embed Images, Fonts, and Files in HTML and CSS — Base64 data URLs encode binary files as text strings for embedding directly in H…
- Base64 Image Encoding — Embed Images in HTML, CSS, and JSON — Base64 image encoding converts image files to text strings for embedding in HTML…
Related tool
Base64 Encoder / Decoder
Encode and decode Base64 strings and files. Client-side, safe for sensitive data.
Written by Mian Ali Khalid. Part of the Encoding & Crypto pillar.