How to Create a mailto Link With Subject, Body, CC and BCC
Build a working mailto link: exact syntax, percent-encoding for spaces and line breaks, multiple recipients, HTML examples and common fixes.

A mailto link is mailto:address?subject=...&body=.... Separate several recipients with commas, add cc= and bcc= as parameters, and percent-encode every value: RFC 6068 says spaces should be %20, line breaks in the body must be %0D%0A, and &, = and ? must be escaped. Inside HTML write the ampersands as &.
A mailto: link opens the visitor's email app with a message already addressed, and optionally pre-filled with a subject and body. It is the simplest "contact us" mechanism on the web, but the details of encoding trip up many developers. This guide gives you the exact syntax from the standard, tested examples and a troubleshooting list.
The basic syntax
mailto:name@example.com
mailto:name@example.com?subject=Hello
mailto:name@example.com?subject=Hello&body=Nice%20to%20meet%20you
The scheme is defined by RFC 6068. Everything after ? is a list of name=value parameters (the standard calls them header fields) joined by &. The address part can contain several comma-separated addresses.
All the fields you can set
| Field | How to write it | Example |
|---|---|---|
| To | Address(es) after mailto:, comma-separated | mailto:a@example.com,b@example.com |
| CC | cc= parameter | ?cc=manager@example.com |
| BCC | bcc= parameter | ?bcc=archive@example.com |
| Subject | subject=, percent-encoded | ?subject=Order%20question |
| Body | body=, percent-encoded | ?body=Hi%20team%2C |
| Reply threading | in-reply-to= (rarely needed) | ?in-reply-to=%3Cmessage-id%40example.com%3E |
RFC 6068 also allows a to parameter inside the query, but calls that form NOT RECOMMENDED because user agents handle it differently, and says an implementation must not produce two To: headers. Put every recipient in the address part.
Percent-encoding: the part that breaks links
URLs cannot contain raw spaces or reserved characters, so values must be percent-encoded. The standard says non-ASCII characters must first be encoded as UTF-8 and each octet then percent-encoded, that &, ; and = have to be escaped when they are not delimiters, and that all spaces SHOULD be encoded as %20:
| Character | Encode as | Note |
|---|---|---|
| Space | %20 | Do not use +; it is not a space in mailto |
| New line | %0D%0A | Carriage return + line feed; required in the body |
& | %26 | Otherwise it starts a new parameter |
= | %3D | Otherwise it splits name and value |
? | %3F | Otherwise it can start a second query |
# | %23 | Otherwise it starts a fragment |
% | %25 | Always encode the percent sign itself |
+ in an address | %2B | The RFC says it MAY be encoded; encoding avoids being read as a space |
| Non-ASCII (Arabic, é, emoji) | UTF-8 percent-encoded | e.g. مرحبا → %D9%85%D8%B1%D8%AD%D8%A8%D8%A7 |
Do not try to do this by hand. In JavaScript, encodeURIComponent() already produces the right form for values (then replace the encoded @ back if you like):
const subject = 'Order #1234: where is it?';
const body = 'Hi team,\n\nMy order has not arrived.';
const href = 'mailto:support@example.com'
+ '?subject=' + encodeURIComponent(subject)
+ '&body=' + encodeURIComponent(body.replace(/\n/g, '\r\n'));
// mailto:support@example.com?subject=Order%20%231234%3A%20where%20is%20it%3F&body=Hi%20team%2C%0D%0A%0D%0AMy%20order%20has%20not%20arrived.
Complete examples
Subject and body with a line break
<a href="mailto:support@example.com?subject=Order%20%231234&body=Hi%20team%2C%0D%0A%0D%0AMy%20order%20has%20not%20arrived.">
Email support
</a>
Multiple recipients, CC and BCC
mailto:sales@example.com,partners@example.com?cc=manager@example.com&bcc=crm@example.com&subject=Partnership%20enquiry
In HTML, escape the ampersands
Inside an HTML attribute write & between parameters. Browsers decode it to & before building the URL. The generator above produces the HTML snippet already escaped.
Why a mailto link does not work (and what to do)
| Symptom | Cause | Fix |
|---|---|---|
| Nothing happens on click | The visitor has no default mail app configured (common on desktop browsers using webmail) | Show the plain address next to the link, or use a contact form |
| Body or subject is cut off | Some clients and browsers truncate very long URLs | Keep the whole link under about 2,000 characters |
| Line breaks are ignored | You used a literal newline or <br> | Use %0D%0A |
| Strange characters | The value was not UTF-8 percent-encoded | Encode the value with encodeURIComponent |
| The second parameter vanishes | A raw & inside a value, or & not escaped in HTML | Encode & as %26 in values |
| HTML formatting not shown | The body is plain text only | Do not put HTML in body |
| Attachment missing | The mailto scheme has no attachment support | Link to a download instead |
Privacy, security and accessibility
- Harvesting: RFC 6068's security section notes that mailto URIs on public web pages expose addresses for harvesting. For a high-traffic page consider a form.
- No silent sending: a mail client SHOULD NOT send a message from a mailto URI without showing the user the full message first, so a link can pre-fill but not send.
- BCC leaks: the RFC warns that addresses in a
bccvalue may leak to others in the same value; use a single BCC address. - Link text: use descriptive text such as "Email our support team" rather than "click here", for accessibility and clarity.
Practical patterns
| Use case | Pattern | Tip |
|---|---|---|
| Support request with order context | ?subject=Order%20%231234&body=Order%20number%3A%201234%0D%0A | Pre-fill the order ID so triage is faster |
| Share a page by email | ?subject=Interesting%20article&body=https%3A%2F%2Fexample.com%2Fpost | Percent-encode the whole URL inside the body |
| Sales enquiry to a shared mailbox | mailto:sales@example.com?subject=Pricing%20enquiry | Route to a role address so it survives staff changes |
| Feedback with a template | ?body=What%20worked%3A%0D%0AWhat%20did%20not%3A%0D%0A | Keep it to two or three prompts |
Keep pre-filled text short and neutral. Long drafts feel pushy, are more likely to be truncated and give visitors something to delete before they can write their own words.
mailto versus a contact form
| Need | mailto | Contact form |
|---|---|---|
| Works with no server | Yes | No, needs a backend or service |
| Works if visitor has no mail app | No | Yes |
| Spam and harvesting exposure | Address is public | Address stays hidden |
| Structured data (order ID, category) | Only via pre-filled text | Real fields and validation |
| Attachments | Not supported | Possible |
For a static site a mailto link is a reasonable first step; add a form when volume or spam grows. If you display the address as text too, check it is spelled correctly with the email address syntax guide.
Testing checklist
- Click the link in the desktop mail app, in webmail registered as the handler and on a phone.
- Check that spaces, non-Latin letters and line breaks appear correctly in the draft.
- Confirm recipients, CC and BCC are in the right fields.
- Check the total length of the link and keep it short.
If you collect these messages in a team inbox, set up proper authentication for the domain so replies and bounces behave: see the SPF, DKIM and DMARC guide.
Frequently asked questions
How do I add a subject and body to a mailto link?
Append ?subject=...&body=... after the address, with both values percent-encoded. In HTML write the ampersand as &.
How do I put a line break in a mailto body?
Use %0D%0A for each line break; RFC 6068 requires this encoding for line breaks in the body. Literal newlines or <br> tags are not reliable.
How do I send to multiple recipients with mailto?
Separate the addresses with commas in the first part: mailto:a@example.com,b@example.com.
Can a mailto link include an attachment?
No. The mailto scheme does not support attachments. Link to a download instead.
Is there a length limit for mailto links?
The standard does not set one, but browsers and mail clients may truncate long links. Staying under about 2,000 characters is a safe rule.


