DEV Community

Volanea
Volanea

Posted on

The text/plain part is not optional

Plenty of sending pipelines generate HTML only, let the library add an empty text part, and move on. It works until a recipient client renders the empty part, or a filter scores the message as suspicious for having no readable alternative.

What the text part is for

It is the fallback for clients that do not render HTML, the accessible version for screen readers, and a signal that the message was composed rather than sprayed. A message with multipart/alternative containing a real text/plain part and a matching HTML part looks like what a person would send.

Generating it properly

Do not strip tags from the HTML at send time — link URLs disappear and the result is unreadable. Compose the text version alongside the HTML: same paragraphs, links written as label <https://url>, lists as dashes. It takes a template, not a converter.

The line-length trap

Text bodies should wrap at 78 characters. A single 400-character paragraph in the text part renders as one endless line in some clients and, worse, can be flagged by filters that treat long lines as machine-generated. Wrap at composition time.

One detail worth checking

If the text part still contains template placeholders after rendering — a stray {{first_name}} — the message looks broken and the fallback is wasted. Assert that no braces survive rendering, in the test suite, not in production.

Volanea renders both parts from the same template variables and fails the render if a placeholder is left unresolved.

Top comments (0)