How to URL Encode a mailto: Link: Subject and Body

Build a mail link with a subject, special characters, and a multiline message without confusing message text with URL or HTML separators.

Quick answer: Keep the recipient and the mailto: structure intact. Percent-encode each subject/body value separately; use %20 for spaces and %0D%0A for body line breaks. In HTML source, write the separator between fields as &.
A mailto link is built from separate subject and body values, each encoded on its own before the fields are assembled.
Subject and message body are separate values; encode each one before joining them into the mailto URI.

Replace YOUR_EMAIL_ADDRESS with the intended recipient before using the example. Encode subject and body as separate values, then assemble them after mailto:YOUR_EMAIL_ADDRESS?. An ampersand inside the message becomes %26; the ampersand between the two fields remains a query separator.

Open the PercentURL URL Encoder to encode a subject or body value. Do not paste the entire mailto: link into a component encoder.

Build a mail link one field at a time

This JavaScript example normalizes all input line endings to CRLF before encoding. It uses encodeURIComponent() on each value—not on the address or the complete URI:

const subject = "Question: plus + and &";
const body = "First line\nSecond line: hello & thanks";

const mailto =
  `mailto:YOUR_EMAIL_ADDRESS?subject=${encodeURIComponent(subject)}` +
  `&body=${encodeURIComponent(body.replace(/\r\n|\r|\n/g, "\r\n"))}`;

console.log(mailto);

The resulting URI is:

A space in a mailto value is percent-encoded as %20; a body line break is represented by %0D%0A.
For mailto values, use %20 for a space and %0D%0A for a CRLF body line break.
mailto:YOUR_EMAIL_ADDRESS?subject=Question%3A%20plus%20%2B%20and%20%26&body=First%20line%0D%0ASecond%20line%3A%20hello%20%26%20thanks

The visible & between subject and body separates fields. The two %26 sequences belong to message text. A plus typed as data becomes %2B; it must not be left where a form-style parser could treat it as a space.

The ampersand in Hello and thanks is message data and becomes %26 inside the encoded body value.
An ampersand typed as message text is data, so encode it as %26 to keep it inside the subject or body.

Put the URI in an HTML link

HTML has its own escaping layer. In an HTML attribute, write the query separator as &; the browser turns that character reference into & in the link value. Do not replace the data's %26 escapes:

<a href="mailto:YOUR_EMAIL_ADDRESS?subject=Question%3A%20plus%20%2B%20and%20%26&amp;body=First%20line%0D%0ASecond%20line%3A%20hello%20%26%20thanks">
  Email support
</a>
A URI field separator is written as & in HTML source; the percent-encoded message data stays unchanged.
In static HTML source, escape the URI field separator as &amp;; keep percent-encoded message characters unchanged.

There are two distinct operations here: percent-encode each header value for the URI, then HTML-escape the URI when placing it in markup. If the href is created in JavaScript with link.href = mailto, do not manually add &amp; to the JavaScript string.

Character-by-character check

Input in a subject or bodyURI formWhy
space%20RFC 6068 recommends percent-encoding spaces this way; + is ambiguous with a literal plus.
literal plus +%2BPreserves it as message data rather than a space-like form value.
ampersand in message text &%26Keeps it inside the field value instead of starting another header field.
line break in body%0D%0ARFC 6068 requires CRLF encoding for body line breaks.
Unicode textUTF-8 bytes, each percent-escaped as neededFor example, é is %C3%A9 in a UTF-8-based mailto URI.
One structural ampersand separates subject and body fields, while %26 is data inside the body value.
Use a literal ampersand between subject and body fields; an encoded %26 inside a value remains message text.

Common mistakes

What the standard does—and does not—promise

RFC 6068 defines subject and body handling and specifies CRLF for body line breaks. It describes body as the first text/plain body part and says implementations cannot be expected to understand more than subject and body. Mail apps can still differ in how they handle a link, so check the composed message before sending. A mailto: link is not a substitute for an HTML email form when you need reliable delivery, attachments, or a consistent experience across devices.

RFC 6068 defines the mailto format, but mail clients can behave differently, so the composed draft should be reviewed.
RFC 6068 defines mailto syntax, but mail applications can handle links differently. Check the draft first.

Use the JavaScript URL encoding guide for component encoding, the URL encode/decode guide for general URL values, or the online URL encoder guide for the tool workflow.

Sources