Keyword: email template screenshot API · Updated August 11, 2026

Email Template Screenshot API: Preview HTML Emails Before They Ship

Transactional and lifecycle emails often ship from code, not a drag-and-drop editor. A checkout receipt, password reset, onboarding nudge, or renewal warning may be generated by React Email, MJML, Rails, Laravel, or a homegrown template engine. Before that template reaches an ESP, reviewers still need a visual artifact they can open, annotate, and approve.

Why this is timely

Email rendering remains fragmented. Litmus' May 2026 email-client report is calculated from more than 1 billion opens and lists Apple, Gmail, Outlook, Yahoo Mail, Google Android, Outlook.com, Thunderbird, Samsung Mail, and newer regional clients in the top group. The same report says almost 90 percent of observed opens report as Apple or Gmail, while mobile and dark mode remain major design considerations.

Developers also build more email HTML in code. React Email documents a render utility that turns React components into HTML strings. MJML remains a common way to compile responsive email markup into HTML, and Gmail's CSS support reference was updated on July 22, 2026. Teams need a fast checkpoint between "template compiled" and "send this to a real inbox test suite."

Positioning: SnapshotFlow is not an inbox emulator. Use it for fast Chromium-rendered previews, pull request artifacts, campaign approval links, and PDF archives. Use a real inbox preview tool when you need Gmail mobile, Outlook desktop, Apple Mail, Yahoo Mail, or device-specific screenshots.

Where a screenshot API fits in email QA

StepToolBest use
Template buildReact Email, MJML, or your server template engineGenerate the final HTML that your ESP will send.
Browser previewSnapshotFlow html inputCreate reviewable PNG, WebP, or PDF artifacts without hosting a temporary page.
Real inbox renderingLitmus, Email on Acid, or another seed-inbox toolCheck client-specific quirks in Gmail, Outlook, Apple Mail, Yahoo Mail, and mobile apps.
Approval recordTicket, pull request, CMS, or campaign checklistStore the preview URL, capture settings, template version, and reviewer decision.

A practical approval workflow

  1. Compile the template. Convert React Email, MJML, or another source format into final HTML. Keep test data realistic: long names, multi-line addresses, missing optional fields, and translated copy.
  2. Capture a 600 pixel desktop preview. Many email templates center around a 600 pixel content column. Use width=600 and a tall enough viewport for the first approval artifact.
  3. Capture a narrow mobile preview. Use width=390, height=844, and viewport_mobile=true to catch stacked-column and small-screen issues in a browser context.
  4. Add a dark-mode check when the template supports it. SnapshotFlow's dark_mode=true emulates prefers-color-scheme: dark. It does not simulate forced color inversion that some email clients apply.
  5. Attach the returned URLs. Use response_type=url for review links, response_type=base64 for inline storage, or format=pdf when the approval process needs a document archive.

1. Render an email HTML file with cURL

The SnapshotFlow API accepts either url or html. For raw HTML, pass a base64-encoded template. This example returns a hosted WebP preview URL.

EMAIL_HTML_B64=$(base64 -i transactional-email.html | tr -d '\n') curl --get "https://api.snapshotflow.com/screenshot" \ -H "X-Api-Key: $SNAPSHOTFLOW_API_KEY" \ --data-urlencode "html=$EMAIL_HTML_B64" \ --data-urlencode "response_type=url" \ --data-urlencode "format=webp" \ --data-urlencode "quality=86" \ --data-urlencode "width=600" \ --data-urlencode "height=1200" \ --data-urlencode "wait_until=networkidle2" \ --data-urlencode "cache=false"

Expected behavior: SnapshotFlow decodes the HTML, renders it in Chromium with a 600 by 1200 viewport, waits for network idle, captures WebP output, stores it, and returns a plain-text download URL. The API does not navigate to a public page because the source is the html payload.

2. Capture desktop, mobile, and dark previews with the Node SDK

The official Node SDK accepts raw HTML and encodes it for the API. This keeps the template pipeline simple: compile HTML, pass it to takeUrl(), and save the returned links.

import { readFile } from "node:fs/promises"; import { SnapshotFlow } from "snapshotflow"; const client = new SnapshotFlow({ apiKey: process.env.SNAPSHOTFLOW_API_KEY, }); const html = await readFile("transactional-email.html", "utf8"); const variants = [ { name: "desktop", width: 600, height: 1200 }, { name: "mobile", width: 390, height: 1200, viewportMobile: true }, { name: "dark-desktop", width: 600, height: 1200, darkMode: true }, ]; for (const variant of variants) { const previewUrl = await client.takeUrl({ html, responseType: "url", format: "webp", quality: 86, waitUntil: "networkidle2", cache: false, ...variant, }); console.log(`${variant.name}: ${previewUrl}`); }

Using React Email or MJML

Render the framework output first, then pass the resulting HTML to SnapshotFlow. React Email's render() utility returns an HTML string. MJML's Node API returns an object with an html field. SnapshotFlow only needs the compiled HTML.

import { render } from "react-email"; import ReceiptEmail from "./emails/receipt"; const html = await render(<ReceiptEmail orderId="ORD-1042" />); const previewUrl = await client.takeUrl({ html, responseType: "url", format: "png", width: 600, height: 1200, cache: false, });

Operational notes and edge cases

  • Keep the browser-preview promise honest. Chromium does not equal Gmail, Outlook desktop, Apple Mail, or Yahoo Mail. Use SnapshotFlow to catch layout, content, responsive, and approval issues early. Use inbox testing for client-specific rendering.
  • Watch URL length. SnapshotFlow's /screenshot endpoint receives html as a query parameter. Base64 expands the template, and proxies can reject long URLs. For large emails, render a protected preview URL and capture that URL instead.
  • Inline or stabilize external assets. If the email depends on remote images or fonts, make sure those URLs are reachable by the renderer. For approval-critical previews, prefer stable asset URLs over local development paths.
  • Record the exact settings. Store width, height, dark-mode flag, template git SHA, data fixture, and capture time next to the preview URL. Reviewers trust screenshots more when they can see how the artifact was created.
  • Use PDF only for records. PDF output is useful for sign-off archives, but PNG or WebP is easier for visual review and ticket comments.
  • Keep secrets out of templates. Do not render real reset tokens, one-time passwords, full payment data, or private customer records into approval screenshots. Use representative fixtures.
Security note: API keys belong in server-side code, CI secrets, or backend jobs. Do not expose SNAPSHOTFLOW_API_KEY in a public client-side preview tool.

FAQ

Can this replace Litmus or Email on Acid?

No. SnapshotFlow gives you fast browser-rendered artifacts from raw HTML or a preview URL. Inbox tools send the email to real client environments and capture client-specific output. Use both when email revenue or compliance risk is high.

Can I render email HTML without hosting it?

Yes. Pass base64 HTML to GET /screenshot as html, or pass a raw HTML string through the Node SDK. For large templates, a preview URL is safer because query strings can hit proxy limits.

Which output should reviewers receive?

Use response_type=url for approval workflows, response_type=base64 when your app stores the image directly, and binary image when a script writes files to disk. Use WebP for smaller artifacts, PNG for lossless review, and PDF for records.

Sources and further reading

Build the preview step once

SnapshotFlow can turn a compiled email template into reviewable screenshots, PDFs, and hosted links from the same API you use for web page captures.

Create a free API key