Skip to content

Instantly share code, notes, and snippets.

@tylermakin
Last active May 7, 2024 21:24
Show Gist options
  • Save tylermakin/d820f65eb3c9dd98d58721c7fb1939a8 to your computer and use it in GitHub Desktop.
Save tylermakin/d820f65eb3c9dd98d58721c7fb1939a8 to your computer and use it in GitHub Desktop.
Multipart MIME Email Guide

Multipart MIME Email Guide

This is a guide on how to send a properly formatted multipart email. Multipart email strings are MIME encoded, raw text email templates. This method of structuring an email allows for multiple versions of the same email to support different email clients.

// Example Multipart Email:
From: [email protected]
To: [email protected]
Subject: Multipart Email Example
Content-Type: multipart/alternative; boundary="boundary-string"

--your-boundary
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Plain text email goes here!
This is the fallback if email client does not support HTML

--boundary-string
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

<h1>This is the HTML Section!</h1>
<p>This is what displays in most modern email clients</p>

--boundary-string--

Different Content-Type Sections

Multipart email strings are composed of sections for each Content-Type version of the email you wish to use. By sending differently formatted versions, you can ensure your recipients are able to see whatever message you are sending, optimized for their email clients' capabilities.

Content-Type Description
text/html This allows the use of HTML (<img>, <table>, <h1>, <p>, etc.)
text/plain For sending an email as only text without formatting
text/watch-html Limited HTML support, similar in effect to rich text formatting
Example use cases of different Content-Type:
  • Send beautifully formatted HTML emails using text/html for an experience similar to that of a web browser
  • For older email clients or recipients who have HTML specifically turned off, use text/plain
  • Apple Watch does not display full HTML emails, so you may send an email without images or styles using text/watch-html
  • The email client on Apple Watch is able to support a format similar to rich-text, albeit with some quirks

Plain Text Format

The plain text format is a means to send an unformatted copy of an email, without images or styles, that will be readable by everyone.

Although HTML makes emails beautiful, plain text makes them functional. In addition to helping prevent your emails from getting caught in the spam filter, a plain text version of your email will allow everyone to see your message, regardless of email client. or settings.

// Plain Text Example
From: [email protected]
To: [email protected]
Subject: Multipart Email Example
Content-Type: multipart/alternative; boundary="boundary-string"

--your-boundary
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Plain text formatted content

--boundary-string--

HTML Format

HTML formatting allows for the use of web languages (HTML and CSS) to style emails, display images, etc. It is important to always include a plain text version of the email when using HTML because some email clients do not support HTML emails, and some recipients prefer plain text format.

HTML format allow for the use of tags such as <h1>Title</h1> and styles such as <p style="color:#777777">Touch of Gray</p> in your emaill. This format also allows for the use of remote images via links <img src="http://example.com/img.png">.

// Example Multipart Email:
From: [email protected]
To: [email protected]
Subject: Multipart Email Example
Content-Type: multipart/alternative; boundary="boundary-string"

--your-boundary
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Plain text formatted content

--boundary-string
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

HTML formatted content

--boundary-string--

Apple Watch Format

You can send emails specifically formatted to the text/watch-html format to allow for Apple Watch users to view your emails on their devices.

// Apple Watch Example
From: [email protected]
To: [email protected]
Subject: Multipart Email Example
Content-Type: multipart/alternative; boundary="boundary-string"

--your-boundary
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Plain text formatted content

--boundary-string
Content-Type: text/watch-html; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline

Apple Watch formatted content

--boundary-string--

The Apple Watch email client has limited support for HTML and is similar in ability to rich text format (see table). Although images are possible in this format, they are quirky and may not display properly.

Rich Text Apple Watch HTML Quirks
Bold <b>ABC123</b>
Italic <i>ABC123</i>
Underline <u>ABC123</u>
Font Color <span style="color:#990000;">ABC123</span> Black text will be changed to white
Alignment <div style="text-align:right;">ABC123</div> left, center, right
Blockquote <blockquote type="cite">ABC123</blockquote> Up to 7 levels deep with shading
Number List <ol><li>ABC123</li></ol>
Bullet List <ul><li>ABC123</li></ul>
Images <img src="cid:...">Text</blockquote> Only embedded images, buggy

** Table Credit: How To Send a Hidden Version of Your Email That Only Apple Watch Will See

Testing Your Email

You may test your email by sending it via a service such as the free PutsMail tool and seeing how it appears in your inbox. Services such as this allow the testing of emails without the need for an email API (Mandrill, Mailgun, Amazon SES, etc.) email service provider, or your own email server.

Although PutsMail does not allow you to send an entire multipart email as a MIME string (all of the examples in this guide), you can send each section (HTML, plain text, watch) individually by copy/pasting the code for each type individually without the headers.

@rinogo
Copy link

rinogo commented Jun 11, 2018

Can you please explain why these examples contain a boundary of --your-boundary as well as a boundary of --boundary-string? From what I know about MIME, I believe --boundary-string should be used throughout, but I could be wrong.

@rinogo
Copy link

rinogo commented Jun 11, 2018

@eltonl
Copy link

eltonl commented Sep 11, 2018

Hi Rinogo

I believe you are correct that whilst the boundary string can be any character combination of your choosing it is normal to use the same string throughout the email.

https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html

@udf2457
Copy link

udf2457 commented Mar 14, 2019

You seem to have missed some rather important parts: https://wiki.apache.org/spamassassin/Rules/MIME_HEADER_CTYPE_ONLY

@HSchuette
Copy link

Thanks for the great guide!
I believe you misspelled ‚plain‘ here.

@tylermakin
Copy link
Author

Thanks for the great guide!
I believe you misspelled ‚plain‘ here.

Fixed, thanks @HSchuette!

@fmainga
Copy link

fmainga commented Aug 12, 2021

Anyone implemented this with nodemailer?

@Devastatia
Copy link

You seem to have missed some rather important parts: https://wiki.apache.org/spamassassin/Rules/MIME_HEADER_CTYPE_ONLY

@udf2457 I got a 404 on your link regarding ctype only. What did I miss?

@udf2457
Copy link

udf2457 commented Dec 17, 2023

@Devastatia that's unfortunate about the Apache removing the page !

Sadly my original comment was almost 5 years ago now, so the honest answer is I can't remember !

@Devastatia
Copy link

@udf2457 No worries. I'm going to base64 encode my images and use data URLs to inline them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment