Charts in Emails

Embed data visualizations in transactional emails, weekly digests, and alerts. One image URL, every email client.

The problem

Email clients do not run JavaScript. No D3. No Chart.js. No canvas. Gmail strips scripts, Outlook blocks inline SVG, and Apple Mail has its own ideas about what CSS means. This is why most teams give up on charts in emails and ship plain tables instead.

The workarounds are painful:

  • Render a chart on a server, save it to S3, and reference the URL – now you are managing image storage and cache invalidation for charts.
  • Use a headless browser to screenshot a web page – slow, brittle, and expensive to maintain.
  • Attach the image to the email and reference it with a cid: URL – increases email size, complicates your sending pipeline, and fails silently in Gmail and Yahoo webmail.

The solution

szum renders charts as images on the server and serves them from a URL. Embed that URL in an <img> tag. Every email client that displays images – Gmail, Outlook, Apple Mail, Yahoo, Superhuman – shows your chart. No JavaScript, no attachments, no build step.

<img
  src="https://szum.io/chart?config={...}"
  alt="Bar chart of weekly active users, rising to 15,900 in March 2026"
  width="540"
  height="360"
  style="display: block; border: 0; width: 100%; max-width: 540px; height: auto;"
/>

How it works

1. Build the chart config. A JSON object that describes your chart. Flat data array, mark type, theme. Typically 5–15 lines.

{
  "version": "2026-03-20",
  "theme": "editorial",
  "format": "png",
  "width": 540,
  "height": 360,
  "title": "Weekly Active Users",
  "marks": [{ "type": "barY" }],
  "data": [
    { "x": "Mar 3", "y": 12400 },
    { "x": "Mar 10", "y": 13100 },
    { "x": "Mar 17", "y": 14800 },
    { "x": "Mar 24", "y": 14200 },
    { "x": "Mar 31", "y": 15900 }
  ]
}

2. Use it as an image URL. URL-encode the config and pass it as a query parameter. With format: "png" in the config, the response is a PNG image – cacheable, fast, and compatible with every email client.

<img
  src="https://szum.io/chart?config=%7B%22version%22%3A..."
  alt="Bar chart of weekly active users, rising to 15,900 in March 2026"
  width="540"
  height="360"
  style="display: block; border: 0; width: 100%; max-width: 540px; height: auto;"
/>

3. Or use signed URLs. For production use, generate a signed URL that authenticates the request without exposing your API key in email HTML. The signed URL works like any other image URL – embed it in an <img> tag. Available on the Pro plan.

Examples

Charts that belong in the emails your product already sends.

Weekly digest

A stacked bar chart in a Monday morning report. Revenue by channel, at a glance – no need to click through to a dashboard.

Inline sparkline

A tiny trend line next to a KPI. 280 pixels wide, no axes, no title – just the shape of the data.

Signups this week

353

+12% vs last week

Ready to add charts to your emails?

One image URL. Every email client.

API reference

With any email provider

szum chart URLs work anywhere <img src> works.

Resend (React Email)

import { Img } from "@react-email/components";

const chartUrl = `https://szum.io/chart?config=${
  encodeURIComponent(JSON.stringify(config))
}`;

<Img
  src={chartUrl}
  alt="Weekly report"
  width={540}
  height={360}
  style={{ display: "block", border: "0", width: "100%", maxWidth: "540px", height: "auto" }}
/>

Postmark (HTML template)

<img
  src="https://szum.io/chart?config={{chartConfig}}"
  alt="Weekly report"
  width="540"
  height="360"
  style="display: block; border: 0; width: 100%; max-width: 540px; height: auto;"
/>

Python (SMTP)

import json, urllib.parse

config = {"version": "2026-03-20", "marks": [...], "data": [...]}
url = f"https://szum.io/chart?config={urllib.parse.quote(json.dumps(config))}"

html = f'''<img
  src="{url}"
  alt="Chart"
  width="540"
  height="360"
  style="display: block; border: 0; width: 100%; max-width: 540px; height: auto;"
/>'''

Why PNG, not SVG

SVG is the natural format for vector charts on the web, but email is not the web. In late 2025, Microsoft began blocking inline SVG in Outlook entirely. The move followed a surge in SVG-based phishing – KnowBe4 reported a 245% increase in SVG files used to deliver malicious payloads. Gmail has never supported inline SVG. Between these two clients, SVG is effectively dead in email.

The other formats have their own problems:

  • SVG – blocked by Outlook (security policy, October 2025), stripped by Gmail. Not viable.
  • WebP – Gmail auto-converts WebP to JPEG, losing transparency. Outlook on Windows fails to render it at all.
  • JPEG – compression artifacts are visible on chart text, grid lines, and sharp edges. No transparency support.
  • PNG – universal support, lossless compression (crisp text and lines), alpha transparency. The right choice for charts.

szum supports both SVG and PNG. For email, set format: "png" in your config. Add scale: 2 for 2× resolution on retina displays – the image is 1080 pixels wide but displays at 540.

Email client compatibility

Hosted PNG images work in every major email client. The difference is whether images load automatically or require a click.

Images shown by default

Gmail (web and mobile), Apple Mail (macOS and iOS), Yahoo Mail, Samsung Email, Superhuman, Hey. Your chart is visible the moment the email is opened.

Images blocked until user allows

Outlook desktop (2007–2024, Microsoft 365) blocks all external images by default. Recipients see a placeholder with your alt text until they click “Download pictures.” Thunderbird and some corporate email gateways behave similarly.

This is not specific to szum – it applies to every image in every email. The mitigation is to write alt text that conveys the key insight and to include the most important number in HTML text near the chart.

When images don't load

Outlook desktop and some corporate email gateways block images by default. How much this affects you depends on your audience – B2B emails see it more than B2C. Design your email so the chart reinforces the message, not carries it alone.

  • Put the key number in text. “Revenue grew 18% to $51K in March” as a paragraph above or below the chart. If the image never loads, the email still delivers the insight.
  • Write descriptive alt text. Not alt="Chart" – instead, describe the chart type, what it shows, and the key takeaway: alt="Bar chart of weekly active users, rising to 15,900 in March 2026". When images are blocked, this text appears in the placeholder.
  • Set width and height on every image. Email clients reserve space for the image before it loads. Without explicit dimensions, the layout collapses and then reflows – or in Outlook, the placeholder is just a tiny icon.
  • Never send image-only emails. An email with no HTML text and only images is the classic spam pattern. Most spam filters flag it. Always include meaningful body text around your charts – context, key metrics, a call to action.

Dark mode

Dark mode in email is fragmented. About 42% of email clients support the prefers-color-scheme CSS media query. The rest either ignore dark mode entirely or invert colors using their own heuristics – sometimes partially, sometimes destructively.

Three things happen depending on the client:

  • No change – the email renders as-is regardless of the OS theme. Gmail desktop web, Yahoo Mail, AOL.
  • Partial inversion – light backgrounds flip to dark, dark text becomes light, but images are untouched. Outlook.com, Outlook mobile.
  • Full inversion – both colors and images are processed. A white chart background becomes a jarring bright rectangle. Gmail app on iOS, Outlook 2021 on Windows.

There is no universal fix. CSS-based image swapping (serving a dark chart variant via prefers-color-scheme) only works in the 42% of clients that support the media query. For the rest, the light image is what recipients see.

The pragmatic approach: a chart with a light background reads as a “content card” in dark mode. It stands out, but it does not break. This is how most data-heavy emails – from Stripe, Linear, Plausible – handle charts in dark mode today.

Tips

  • Keep charts under 540px wide. Most email clients render at 600px max width. Leave room for padding.
  • Use scale: 2 for retina. Export at 2× resolution, then constrain the display size with HTML attributes and inline CSS: style="width: 100%; max-width: 540px; height: auto;". The HTML width attribute is required for Outlook, which ignores CSS width.
  • Add display: block to every image. Without it, some clients add unwanted spacing below images. border: 0 removes the default border Outlook adds around linked images.
  • Use signed URLs for production. Without a signed URL, chart requests are keyless and IP-rate-limited. Signed URLs authenticate against your account, giving you higher render limits and access to Pro features like custom themes. Available on the Pro plan.

Why not just attach an image?

Email attachments with cid:references seem simpler but cause real problems. They increase email size significantly, complicate your sending pipeline, and trigger spam filters more often than hosted images. Gmail and Yahoo webmail are unreliable with CID images – they sometimes render, sometimes don't, with no clear pattern. macOS Mail occasionally displays CID images as separate attachments instead of inline.

External image URLs are lighter, cacheable by email clients, and let you update the chart without resending the email. With szum, the chart URL is the chart – no intermediate storage, no cleanup, no infra to maintain.

Frequently asked questions

What image format should I use for charts in email?
PNG. It is the only format that combines universal email client support, lossless rendering (no artifacts on text and lines), and transparency. SVG is blocked by Outlook and stripped by Gmail. WebP is degraded by Gmail and broken in Outlook on Windows. JPEG creates visible compression artifacts on chart text. Set format: "png" in your szum config for email use.
Do charts work in Outlook?
Yes. Outlook displays hosted PNG images like any other image. The caveat is that Outlook desktop blocks all images by default until the recipient clicks “Download pictures.” This applies to every image in every email, not just charts. Include the key data point as HTML text so the email is useful even before images load.
How do email charts look in dark mode?
It depends on the client. Most show the chart image unchanged. Some clients with aggressive dark mode (Gmail iOS, Outlook 2021) invert surrounding colors but leave images alone – the chart appears as a light content card on a dark background. CSS-based image swapping only works in about 42% of email clients.
What is the maximum image width for email?
The industry standard maximum content width is 600px. We recommend 540px for chart images to leave room for email padding. Export at 2× resolution with scale: 2 for crisp rendering on retina screens, then set width="540" on the <img> tag to constrain the display size.
How is szum different from QuickChart?
Both serve chart images from a URL. szum is designed around visual quality – curated themes, typographic defaults, and mark types that produce publication-ready charts without manual styling. See the full comparison.