Email marketing teams send hundreds of campaigns per year. Regulations like GDPR and CAN-SPAM, combined with internal compliance requirements, often mandate archiving every email that goes out. While email service providers store campaign data, having a PDF archive gives you a portable, searchable, and legally admissible record that does not depend on a third-party vendor.
Why Archive Emails as PDF?
- Regulatory compliance — Financial and healthcare industries require durable records of all customer communications.
- Legal protection — In disputes, a timestamped PDF is stronger evidence than a screenshot.
- Vendor independence — If you switch email platforms, your archive remains intact.
- Internal review — Product and legal teams can review past campaigns without accessing the email platform.
- Client reporting — Agencies can deliver campaign portfolios as polished PDF documents.
The Challenge: Email HTML Is Not Web HTML
HTML emails use a subset of HTML and CSS that dates back to the early 2000s. Email clients have wildly inconsistent rendering engines, so email developers rely on:
- Table-based layouts instead of Flexbox or Grid
- Inline styles instead of external stylesheets
- Deprecated attributes like
bgcolor,align, andcellpadding - Conditional comments for Outlook (
<!--[if mso]>) - VML (Vector Markup Language) for Outlook backgrounds
When converting email HTML to PDF, you need to handle these quirks without breaking the layout.
Preprocessing Email HTML
Before sending email HTML to a PDF API, clean it up:
const { JSDOM } = require('jsdom');
function preprocessEmailHTML(emailHtml) {
const dom = new JSDOM(emailHtml);
const document = dom.window.document;
// Remove Outlook conditional comments
const html = emailHtml
.replace(/<!--\[if[^\]]*\]>.*?<!\[endif\]-->/gs, '')
.replace(/<!--\[if[^\]]*\]>.*?<!\[endif\]-->/gs, '');
// Remove tracking pixels (1x1 images)
document.querySelectorAll('img').forEach(img => {
if (img.width <= 1 || img.height <= 1) {
img.remove();
}
});
// Ensure images use absolute URLs
document.querySelectorAll('img').forEach(img => {
if (img.src && !img.src.startsWith('http')) {
img.src = `https://cdn.example.com${img.src}`;
}
});
// Add print-friendly styles
const style = document.createElement('style');
style.textContent = `
@media print {
body { width: 100% !important; margin: 0 !important; }
table { width: 100% !important; }
img { max-width: 100% !important; height: auto !important; }
}
`;
document.head.appendChild(style);
return dom.serialize();
}
Converting to PDF
With the preprocessed HTML, generate the PDF:
async function archiveEmail(campaignId, emailHtml, subject) {
const cleanHtml = preprocessEmailHTML(emailHtml);
const response = await fetch('https://api.tongorender.io/v1/pdf', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.TONGORENDER_API_KEY,
},
body: JSON.stringify({
html: cleanHtml,
format: 'A4',
margin: { top: '15mm', bottom: '15mm', left: '10mm', right: '10mm' },
displayHeaderFooter: true,
headerTemplate: `<div style="font-size:9px;color:#999;width:100%;text-align:center">${subject} — Campaign #${campaignId}</div>`,
footerTemplate: '<div style="font-size:9px;color:#999;width:100%;text-align:center">Archived on ' + new Date().toISOString().split('T')[0] + ' — Page <span class="pageNumber"></span></div>',
}),
});
if (!response.ok) throw new Error(`Archive failed: ${response.statusText}`);
return Buffer.from(await response.arrayBuffer());
}
Batch Archiving with Mailchimp
If you use Mailchimp (or a similar provider), you can pull campaign HTML via their API and archive every campaign automatically:
const mailchimp = require('@mailchimp/mailchimp_marketing');
mailchimp.setConfig({ apiKey: process.env.MAILCHIMP_API_KEY, server: 'us1' });
async function archiveAllCampaigns() {
const campaigns = await mailchimp.campaigns.list({ count: 100, status: 'sent' });
for (const campaign of campaigns.campaigns) {
const content = await mailchimp.campaigns.getContent(campaign.id);
const pdf = await archiveEmail(campaign.id, content.html, campaign.settings.subject_line);
fs.writeFileSync(`archives/${campaign.id}.pdf`, pdf);
console.log(`Archived: ${campaign.settings.subject_line}`);
}
}
Tips for Perfect Email-to-PDF Conversion
- Set a fixed width — Emails are typically 600px wide. Set the viewport or a wrapper to match.
- Handle web fonts — Many email clients strip web fonts, but PDFs can render them. Keep the font links.
- Remove interactive elements — Buttons with JavaScript handlers or form elements will not work in PDF.
- Test dark mode variants — If your email has dark mode CSS, decide which version to archive.
TongoRender handles table-based email layouts, inline styles, and legacy HTML attributes without issue. The Chromium rendering engine treats email HTML just like any web page.
Archive your emails with TongoRender — 100 free renders per month, no credit card required.