Plain text vs HTML email: why both matter (and how to ship both)
Why HTML-only emails get filtered, what a clean multipart/alternative looks like, and the four-line MIME structure to copy.
ContentMIMEDeliverability
Sending HTML without a plain-text alternative is the single most common content mistake we see in WillItInbox reports. SpamAssassin penalizes it. Accessibility tools penalize it. Old clients penalize it. The fix is a four-line MIME header change with no downside.
The MIME structure
Minimal multipart/alternativetxt
Content-Type: multipart/alternative; boundary="b1"
--b1
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
Welcome to WillItInbox.
Visit https://willitinbox.com/test to run your first check.
--b1
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
<p>Welcome to <strong>WillItInbox</strong>.</p>
<p><a href="https://willitinbox.com/test">Run your first check.</a></p>
--b1--- Outer Content-Type is
multipart/alternative— receivers know to pick the best part. - Plain-text part comes first. Older clients render the first part they understand.
- Both parts must contain the same content. Significant divergence is itself a spam signal.
- Boundary string can be anything unique — UUIDs are conventional.
Generating the plain-text part
| Approach | Quality | When to use |
|---|---|---|
| Hand-write both parts | Best | Templates, transactional |
| Auto-convert from HTML | Good | Marketing campaigns, bulk |
| Auto-strip HTML tags | Bad | Never |
| Identical to HTML body | Worst — defeats the point | Never |
Conversion tools
- html-to-text (npm) — node library; produces solid output for marketing emails.
- Mailparser in your ESP — most major providers auto-generate a text part if you only supply HTML.
- Pandoc — overkill but produces excellent results for newsletters with structure.
- Markdown source — write your email in Markdown, render once to HTML and once via stripping for plain-text.
Common mistakes
| Mistake | Why it hurts |
|---|---|
| No plain-text part at all | +0.7 SpamAssassin, accessibility fail |
| Plain-text part empty | Treated as missing |
| Plain-text contains HTML tags | Looks broken to text-only clients |
| Plain-text wildly different from HTML | Looks like cloaking — manual review |
| Boundary string in body | Breaks parsing entirely |
| Wrong order (HTML first) | Older clients render HTML source as text |
Where the plain-text part is actually used
- Apple Watch notifications — show plain-text excerpt.
- iOS / Android lock screen previews — text part wins for snippets.
- Screen readers — plain-text is significantly more accessible.
- Text-only mail clients — Mutt, Alpine, terminal users still exist.
- Spam filters — every modern engine analyzes both parts.
Frequently asked questions
Keep reading