SVG Icons in Email: Why They Break and What Actually Renders
SVG is the right format almost everywhere — except the inbox. Drop an inline `<svg>` into an HTML email and it will look perfect in your design tool, then vanish or render as a broken-image box for a large slice of your recipients. The reason isn't a bug you can fix with cleaner markup: it's that several major email clients deliberately strip or fail to render SVG, and others route images through a proxy that can't process it. This guide explains, in plain terms, exactly which clients kill SVG and why, then walks the technique that has worked for years — shipping a raster PNG with the right fallback — and the details that make it crisp instead of fuzzy: baking color into the asset and hosting it on a reliable URL. It also covers a specific convenience worth knowing about: when you design with BuilderJS, its email export step automatically swaps each styled icon SVG for a pre-rendered PNG and carries the `aria-label` across as the image `alt`, so you get icons that render everywhere without hand-managing fallbacks. BuilderJS is the editor you embed and self-host — it builds the markup; you bring your own sending. Everything below sticks to what email clients actually do in 2026 and what the export pipeline actually does.
Mount it
// BuilderJS's email export swaps every styled-icon SVG (carrying a
// data-social-glyph marker) for a pre-rendered PNG <img>, copying
// width/height and mapping aria-label -> alt. This is the real shape
// of pipeline step 4.5 (EmailExportPipeline.socialStyledSvgToImg):
// IN — what the editor renders on the canvas (style:platform marker):
// <svg data-social-glyph="circle-dark:twitter" width="32" height="32"
// aria-label="X (Twitter)" role="img"> ... </svg>
// OUT — what the email export emits (renders in every client):
// <img src="<mediaUrl>/master/assets/image/icons-styled/circle-dark/twitter.png"
// width="32" height="32" alt="X (Twitter)"
// style="display:block;border:0;outline:none;text-decoration:none;">
// You never call this directly — it runs inside the export, but ONLY when
// the builder is in email output mode (outputMode/artefactType: 'email').
// Your job is just to design, persist the JSON, and ship the HTML yourself:
const builder = new Builder({ /* containers... */, outputMode: 'email' });
const json = builder.getData(); // lossless design state (JSON)
const emailHtml = builder.getHtml(); // email-mode output, icons already PNG
// POST emailHtml to YOUR backend, then send via YOUR ESP/SMTP.
// BuilderJS builds the markup; you bring the sending + the CDN that
// hosts the icon PNGs. No npm package — load builder.js (window.Builder).
Why SVG dies in the inbox (Outlook, Gmail web, Yahoo)
SVG support in email is genuinely poor, and it fails in two different ways. First, several clients strip or refuse to render SVG outright. Desktop Outlook on Windows renders mail through Microsoft's Word engine, which has no meaningful SVG support — your icon becomes a broken-image placeholder or nothing at all. Yahoo Mail and AOL strip `<svg>` from message bodies as part of their sanitizing. (Email client SVG support is documented at Can I email, https://www.caniemail.com/features/image-svg/, as of June 2026; verify against current data before shipping.) Second — and this is the part people miss — Gmail's web client routes every image through Google's image proxy (googleusercontent.com), and that proxy historically does not serve inline or referenced SVG the way it serves PNG and JPEG, so even an SVG that isn't stripped often won't display. So between aggressive sanitizing in some clients and proxy handling in others, SVG can't be your delivery format for icons. It's not about writing better SVG; the format itself isn't safe to depend on across the inbox landscape.
The fallback that actually renders: ship a PNG
The technique that survives every major client is unglamorous and reliable: render the icon as a raster PNG and reference it with a plain `<img>`. PNG is universally supported — Outlook's Word engine, Gmail's proxy, Yahoo, Apple Mail, every webmail and mobile app render it. Some teams reach for `<picture>` with an SVG `<source>` and a PNG `<img>` fallback, betting that capable clients take the SVG and the rest fall back to PNG. That's a defensible belt-and-suspenders pattern for the web, but in email the SVG branch buys you almost nothing — the clients that strip SVG often strip or ignore `<picture>` and `<source>` too, and the ones that proxy images won't fetch the SVG anyway. The pragmatic answer is to skip the cleverness and just ship the PNG as the real asset. Set explicit `width` and `height` so the layout holds before the image loads, and always include a meaningful `alt` attribute — because Outlook and many clients block images by default, your `alt` text is what the recipient sees until they choose to load images. For retina sharpness, render the PNG at 2x the displayed size and constrain it with the displayed `width`/`height`.
Bake the color in, and host it somewhere reliable
Two practical details separate a crisp icon from a fuzzy or invisible one. First: bake the color into the PNG. With inline SVG you can recolor an icon with CSS `fill` and `currentColor`, but those tricks don't survive into a PNG and email CSS support is unreliable regardless. So render the icon in the exact brand color you want — a white glyph for a dark footer, a colored glyph for a light one — and export that as the asset. The color lives in the pixels, not in a stylesheet the client might strip. Second: host it on a stable, public, absolute URL. Email images can't be relative paths or data-URIs you can count on (some clients refuse base64 `<img>` data, and large data-URIs bloat the message toward Gmail's ~102KB clipping threshold). Put your icon PNGs on a CDN or any reliable static host, reference them with a full `https://` URL, and make sure the host serves the right `Content-Type` and permissive caching. Gmail's proxy will fetch and re-cache the image; a flaky or auth-gated origin means a broken icon for a chunk of your list.
How BuilderJS handles its icon SVGs for you
This is where an export-aware editor removes the manual work. BuilderJS is a drag-and-drop builder library you embed in your own app to design HTML email and pages; you author normally, and its EmailExportPipeline rewrites the markup for inbox safety on export. One of its steps (4.5 in the pipeline) targets styled social icons specifically: when you pick an icon style, BuilderJS renders each icon as an inline `<svg>` carrying a `data-social-glyph="style:platform"` marker. At export, the pipeline finds every SVG with that marker and swaps it for an `<img>` pointing at a pre-rendered PNG that ships with the asset set (`master/assets/image/icons-styled/{style}/{platform}.png`) — the styled, full-color raster of that exact icon. It copies the SVG's `width`/`height` onto the `<img>`, and crucially it carries the SVG's `aria-label` across as the image `alt`, so the accessible name (the platform's label) becomes the fallback text recipients see when images are blocked. The result is icons that render crisply in Outlook, Gmail, and Yahoo with zero fallback management on your part — a capability nearly no competing editor advertises. Honest scope: this auto-swap runs only when the builder is in email output mode, and it's gated on the `data-social-glyph` marker, so it covers BuilderJS's own styled icons; any custom inline SVG you paste in without that marker passes through untouched, and for those you'd still ship your own PNG using the rules above.
Build once, export inbox-safe, send with your own stack
The icon swap is one step in a pipeline that exists to make the design you see survive real clients. From the same JSON design, BuilderJS's email export converts modern flexbox and grid layouts to nested tables, adds MSO conditional comments and ghost tables for Windows Outlook, generates `@media (max-width:600px)` rules for mobile column stacking, applies fluid-image defenses (`max-width:100%; height:auto` on every image), and runs a CSS inliner that pushes safe declarations onto the elements — alongside the styled-icon-to-PNG swap. You design in any framework (React, Vue, Svelte, Angular, or plain HTML), call `getData()` to persist the lossless JSON, and export Outlook-safe HTML when you're ready (instantiate the builder in email output mode, or call its email-export entry point). The boundary stays clean: BuilderJS builds and exports the markup and references the icon URLs; it does not send email, host images, or manage lists. You hand the exported HTML to your own ESP or SMTP service, and you host the assets on your own CDN. The 30+ templates and 200+ samples that ship with it are Litmus-tested across 22 clients, so the export — icons included — is checked against the same fussy inboxes described above.
Frequently asked questions
-
Why don't my SVG icons show up in Outlook and Gmail?
Because those clients don't reliably render SVG in email. Desktop Outlook on Windows uses Microsoft's Word engine, which has no real SVG support, and Yahoo and AOL strip `<svg>` during sanitizing. Gmail's web client adds a second problem: it proxies every image through googleusercontent.com, and that proxy historically doesn't serve SVG the way it serves PNG and JPEG. The fix isn't cleaner SVG — it's shipping a PNG instead. (See caniemail.com SVG support data, as of June 2026, and verify before shipping.)
-
Should I use <picture> with an SVG source and PNG fallback?
In email, not really. The `<picture>`/`<source>` pattern works on the web, but the clients that strip SVG often strip or ignore `<picture>` and `<source>` too, and the proxy-based clients won't fetch the SVG branch anyway — so the SVG source buys you almost nothing. The pragmatic approach is to ship the PNG as the real `<img>` asset with explicit width, height, and meaningful alt text. That single asset renders in every major client.
-
Does BuilderJS convert my icons to PNG automatically?
Yes, for its styled social icons, when you export in email output mode. When you pick an icon style, BuilderJS tags each icon SVG with a data-social-glyph marker, and its EmailExportPipeline (step 4.5) swaps every marked SVG for an `<img>` pointing at the pre-rendered, full-color PNG that ships with the asset set — carrying the width, height, and aria-label (as the image alt) across. It's gated on that marker, so BuilderJS's own styled icons are handled automatically; a custom SVG you paste in without the marker passes through untouched, and you'd ship a PNG for that yourself.
-
Will my icon keep its color and accessible label after the swap?
Yes. The PNG BuilderJS swaps in is the styled, full-color raster of that exact icon, so the color is baked into the pixels rather than relying on email CSS that clients might strip. The export also copies the SVG's aria-label onto the new `<img>` as its alt attribute, which doubles as the fallback text a recipient sees when their client blocks images by default — common in Outlook and elsewhere.
-
Does BuilderJS host the icon images or send the email?
No. BuilderJS is the editor you embed and self-host — it builds the email HTML, swaps styled icon SVGs to PNG references, inlines CSS, and produces the markup, and that's where its job ends. It does not send email, host images, run a CDN, or manage lists. You host the icon PNGs on your own storage or CDN and hand the exported HTML to your own ESP or SMTP service. The builder owns the markup; you own the delivery.