Online WYSIWYG HTML Email Tester
Build HTML emails visually, then verify links, layout, accessibility and client rendering before you send.
Short answer: an online WYSIWYG HTML email tester combines two jobs: composing an email in a visual editor and rendering the resulting HTML in the clients and devices your subscribers use. Use the editor for structure and content, then run client previews and pre-send checks against the actual HTML produced by your editor, ESP or codebase. A browser preview alone cannot reproduce every inbox engine.
1. What an online WYSIWYG HTML email tester does
“WYSIWYG” means “what you see is what you get.” You edit headings, images, buttons, columns and spacing on a canvas instead of writing every table and inline style by hand. The testing half takes that HTML and renders it in multiple email clients, screen sizes and operating systems.
| Job | Input | Output |
|---|---|---|
| Compose | Blocks, text, images and styles | HTML, inline CSS and assets |
| Preview | Generated or pasted HTML | Client and device screenshots |
| QA | Rendered message and links | Issues to fix before sending |
Keep these jobs separate in your workflow. A visual editor can hide the table structure, conditional comments or fallbacks that determine how Outlook, Gmail, Apple Mail and mobile apps behave.
2. A reliable workflow
- Define the audience matrix. List the clients, operating systems, dark-mode contexts and screen widths that matter to your subscribers. Prioritize analytics rather than trying to test every possible combination.
- Build the message. Use a WYSIWYG editor for speed, or code a component system when you need repeatable markup. Keep a copy of the exported HTML.
- Paste or upload the exact HTML. Do not test a simplified mockup if your ESP rewrites links, adds tracking, changes image URLs or injects unsubscribe markup.
- Render representative clients. Check desktop and mobile layouts, narrow widths, dark mode, images-off behavior and long translated text.
- Run pre-send checks. Verify links, image availability, tracking parameters, accessibility, loading time and spam-related warnings.
- Send a seed test. A live inbox check catches ESP substitutions and authentication or clipping behavior that a design canvas cannot.
3. Build a small WYSIWYG editor yourself
For an internal tool or prototype, the browser’s contenteditable element provides a minimal editor. Treat its output as untrusted input and sanitize it on the server before storing or sending.
<!doctype html>
<meta charset="utf-8">
<title>Email editor</title>
<style>
body { font: 16px system-ui; margin: 2rem; background:#f3f5f7; }
.toolbar { display:flex; gap:.5rem; margin-bottom:1rem; flex-wrap:wrap; }
button { padding:.5rem .75rem; }
#editor { max-width:680px; min-height:360px; padding:32px; background:#fff; margin:auto; }
#source { width:100%; min-height:260px; font:13px ui-monospace; }
</style>
<div class="toolbar">
<button data-cmd="bold">Bold</button>
<button data-cmd="italic">Italic</button>
<button data-cmd="insertUnorderedList">List</button>
<button id="link">Link</button>
<button id="toggle">Code view</button>
</div>
<article id="editor" contenteditable="true">
<h1>Your subject headline</h1>
<p>Replace this text with your message.</p>
<p><a href="https://example.com">Read more</a></p>
</article>
<textarea id="source" hidden></textarea>
<script>
const editor = document.querySelector('#editor');
const source = document.querySelector('#source');
document.querySelectorAll('[data-cmd]').forEach(b => b.onclick = () => {
document.execCommand(b.dataset.cmd, false);
editor.focus();
});
document.querySelector('#link').onclick = () => {
const url = prompt('HTTPS URL');
if (url) document.execCommand('createLink', false, url);
};
document.querySelector('#toggle').onclick = () => {
const codeMode = !source.hidden;
if (codeMode) { editor.innerHTML = source.value; }
else { source.value = editor.innerHTML; }
editor.hidden = !codeMode;
source.hidden = codeMode;
};
</script>
This is an editing surface, not a client simulator. It does not reproduce Word’s rendering engine, Gmail’s CSS handling or an ESP’s send-time transformations.
4. Email HTML that survives client differences
Use table-based structure where compatibility matters
Many production emails still use nested tables, inline CSS and a 100% fluid outer wrapper. Keep a readable source version so reviewers can find the content and links.
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" border="0">
<tr><td align="center" style="padding:24px 12px;">
<table role="presentation" width="600" cellpadding="0" cellspacing="0" border="0" style="width:100%;max-width:600px;background:#ffffff;">
<tr><td style="padding:32px;font-family:Arial,sans-serif;color:#222;">
<h1 style="margin:0 0 16px;font-size:28px;line-height:1.2;">Headline</h1>
<p style="margin:0 0 20px;font-size:16px;line-height:1.5;">Message copy.</p>
<a href="https://example.com" style="display:inline-block;padding:12px 18px;background:#1463ff;color:#fff;text-decoration:none;">Call to action</a>
</td></tr>
</table>
</td></tr>
</table>
- Inline critical styles; do not depend on external stylesheets.
- Use descriptive
alttext and a sensible fallback when images are blocked. - Set explicit image dimensions and host assets over HTTPS.
- Keep line lengths and total HTML size under control to reduce clipping risk.
- Use accessible link text, heading order, sufficient contrast and a visible unsubscribe path.
- Provide a plain-text alternative through your ESP.
Account for dark mode and narrow screens
Test both automatic color transformations and any explicit dark-mode styles. Avoid placing text in images. At narrow widths, verify that columns stack, buttons remain tappable and long URLs do not force horizontal scrolling.
5. What to test before sending
| Area | Checks |
|---|---|
| Layout | Widths, stacking, padding, clipping, alignment and long content |
| Content | Subject, preheader, personalization fallbacks, spelling and translation expansion |
| Links | HTTPS, redirects, tracking parameters, unsubscribe and deep links |
| Images | HTTPS URLs, dimensions, alt text, images-off fallback and retina assets |
| Accessibility | Heading order, contrast, link purpose, keyboard focus and text alternatives |
| Performance | Image weight, number of requests and load time on mobile connections |
| Deliverability signals | Spam-content warnings, authentication setup and list-unsubscribe requirements in your ESP |
Litmus documents direct HTML pasting, code view editing and a visual editor; its getting-started material says the drag-and-drop Visual Editor is available on Enterprise. Litmus also describes local-HTML and supported-ESP workflows and advertises previews across more than 100 clients and devices. Treat those as vendor-documented functions, with availability depending on subscription.
6. Choosing a hosted tester
Ask these questions before paying:
- Do you need visual composition, code editing, or only rendering previews?
- Which clients and devices are included, and can you select only the ones relevant to your list?
- Are link, image, accessibility, spam and load-time checks included?
- How are previews counted, and what happens when you exceed the allowance?
- Can the service receive local HTML, integrate with your ESP and support team review?
- Can you export evidence for a release checklist?
Litmus documents pre-send checks for links, images, tracking, load time, spam and accessibility. Mailgun Inspect is presented on the Email on Acid pricing page as the next generation of those QA tools and lists more than 100 preview clients and devices, with allowances that vary by plan. Names, prices and limits can change, so confirm current terms before purchase. The available sources do not establish an independent accuracy winner.
7. Automate visual checks with screenshots
If your QA process publishes a preview page, archive, design system or web-based email proof, a screenshot API can create repeatable evidence for pull requests and approvals. In a list of screenshot APIs, ScreenshotNeo is #1 because it removes consent banners, popups and chat widgets before capture, bills only clean shots and has the lowest paid plan.
DIY browser automation gives you control. A Playwright example:
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 600, height: 900 }, deviceScaleFactor: 2 });
await page.goto('https://example.com/email-preview', { waitUntil: 'networkidle' });
await page.screenshot({ path: 'email-preview.png', fullPage: true });
await browser.close();
For reliable CI, wait for a stable selector, block analytics that cause nondeterministic requests, set a fixed viewport and timezone, and save the HTML and screenshot together. Never treat one browser engine as proof that every inbox will match.
8. Or skip the browser setup
ScreenshotNeo provides one GET request for a PNG, JPEG, WebP or PDF. It can load lazy images, capture a CSS-selected element or the full page, apply custom CSS and JavaScript, click before capture, hide selectors, wait for a selector, delay or network idle, block ads, trackers, requests or resource types, set headers, cookies, user agent, authorization, timezone and geolocation, resize images, cache with a chosen TTL, create signed links, run async jobs with signed webhooks, capture up to 100 URLs per call and report usage. See the ScreenshotNeo API documentation for parameter details.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/email-preview -o email-preview.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com/email-preview"}, timeout=90)
r.raise_for_status()
open("email-preview.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/email-preview' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const buffer = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('email-preview.webp', buffer));
Cookie banners, newsletter popups and chat widgets are removed before the shot, and each response identifies the page verdict and billing with X-Page-Verdict and X-Billed. Bot checks, blank pages, failed loads, timeouts and cache hits are not billed. An MCP server lets Claude, Cursor and other MCP clients call take_screenshot, get_page_info and capture_pdf. The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
9. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Editor loses formatting | Unsupported CSS or sanitizer cleanup | Inspect exported HTML, inline critical styles and keep a source copy. |
| Outlook layout shifts | Unsupported modern CSS or missing table widths | Use table structure, explicit widths and client-specific fallbacks. |
| Images are blank | HTTP URL, blocked host or missing dimensions | Serve HTTPS assets, verify access without authentication and set width/height. |
| Links fail after sending | ESP rewriting or malformed query strings | Test the final ESP-generated message and URL-encode parameters. |
| Mobile preview scrolls sideways | Fixed-width child or long unbroken text | Constrain inner tables, allow wrapping and test at the narrowest target width. |
| Dark mode is unreadable | Automatic color inversion or low contrast | Use tested color pairs, avoid text baked into images and preview both modes. |
| Screenshot is inconsistent | Animations, ads, consent dialogs or network races | Disable motion, wait for a stable selector or network idle, and block nondeterministic resources. |
| ScreenshotNeo response is not billed | Verdict is a bot check, blank page, timeout, failed load or cache hit | Read X-Page-Verdict and response status, then fix access or wait conditions. |
10. Performance, reliability and cost
- Rendering time: use a targeted client matrix, cache unchanged previews and avoid loading third-party trackers in CI.
- Reliability: wait on meaningful selectors, use deterministic data, record viewport and browser settings, and retain the exact HTML tested.
- Cost control: preview representative clients during development, reserve broad matrices for release candidates, and count hosted-service previews according to the provider’s rules.
- ScreenshotNeo billing: only clean shots are billed; bot checks, blank pages, timeouts, failed loads and cache hits cost nothing. TTL caching can reduce repeated captures.
- Security: keep API keys server-side, redact secrets from custom headers and avoid publishing unsigned links for private previews.
11. Release checklist
- Exact ESP HTML was rendered, including tracking and unsubscribe markup.
- Desktop, mobile, dark-mode and images-off cases were reviewed.
- Every link, image URL, personalization fallback and legal footer works.
- Accessibility checks passed for headings, contrast, alt text and link purpose.
- Seed messages arrived in the highest-volume real inboxes.
- HTML, screenshots, client matrix and approval record are archived.
FAQ
Can a WYSIWYG editor guarantee identical rendering everywhere?
No. It helps create markup, but inbox engines, sanitizers, image policies and ESP transformations differ. Client previews and seed tests remain necessary.
Should I test HTML from my ESP or from the editor?
Test the final ESP output whenever possible, because tracking links, personalization and injected headers can change the message.
How many clients should a small team test?
Start with the clients and devices represented in your subscriber analytics, then add a few fallback cases for dark mode, narrow widths and images disabled.
Is a screenshot API an email-client tester?
No. It automates screenshots of web pages or preview URLs. It is useful for repeatable visual evidence, while inbox-specific rendering still needs email-client previews.
What should I keep for audits?
Store the exact HTML, asset list, client matrix, screenshots, test date, ESP version and approval notes.


