The mailto: scheme opens the user's email client with pre-filled fields. It's essential for contact links and integrating email functionality in web pages.
Mailto links are one of the oldest URL schemes still in active use, and they remain the simplest way to let users send you an email. Unlike contact forms, mailto links work without any server-side code and respect the user's preferred email application.
Key Takeaways
- 1Mailto opens the default email client
- 2Parameters include to, cc, bcc, subject, and body
- 3All parameter values must be URL-encoded
- 4Line breaks in body must be %0D%0A (RFC 6068)
- 5Multiple recipients separated by commas
"The 'mailto' URI scheme is used to identify resources that are reached using Internet mail. In its simplest form, a 'mailto' URI contains an Internet mail address."
Mailto URL Structure
Mailto URLs follow a straightforward structure: the recipient comes after the scheme, and optional parameters (subject, body, cc, bcc) follow as query parameters. Understanding this structure helps you construct links that pre-fill the right fields.
# Basic mailto URL
mailto:email@example.com
# With parameters
mailto:email@example.com?subject=Hello&body=Message
# Full structure
mailto:recipient@example.com?cc=copy@example.com&bcc=blind@example.com&subject=Subject%20Line&body=Email%20body
# Components:
mailto: - Scheme
email@example.com - Primary recipient (can be empty)
? - Query string separator
subject= - Email subject
body= - Email body
cc= - Carbon copy recipients
bcc= - Blind carbon copy recipientsNotice that the primary recipient appears directly after mailto:, while additional recipients and other fields use query parameters. You can even omit the primary recipient entirely if you want a generic "share via email" link.
Let's look at each available parameter in detail and see how they map to email client fields.
Mailto Parameters
The table below lists all standard mailto parameters. While email clients generally support these, some webmail services may ignore certain parameters like bcc for privacy reasons.
| Parameter | Purpose | Example |
|---|---|---|
| to | Primary recipient | to=user@example.com |
| cc | Carbon copy | cc=copy@example.com |
| bcc | Blind carbon copy | bcc=hidden@example.com |
| subject | Email subject | subject=Hello |
| body | Email body | body=Message%20text |
Now let's see these parameters in action with real-world HTML examples you can copy and adapt for your own projects.
Mailto Examples
The following examples progress from simple to complex, showing common patterns for contact links, support requests, and sharing functionality.
<!-- Simple email link -->
<a href="mailto:support@example.com">Contact Support</a>
<!-- With subject -->
<a href="mailto:support@example.com?subject=Help%20Request">
Get Help
</a>
<!-- With subject and body -->
<a href="mailto:support@example.com?subject=Question&body=Hi%2C%0D%0A%0D%0AI%20have%20a%20question.">
Contact Us
</a>
<!-- Multiple recipients -->
<a href="mailto:sales@example.com,support@example.com">
Contact Team
</a>
<!-- All parameters -->
<a href="mailto:john@example.com?cc=jane@example.com&bcc=log@example.com&subject=Meeting%20Request&body=Hi%20John%2C%0D%0A%0D%0ACan%20we%20meet%20tomorrow%3F%0D%0A%0D%0ABest%2C%0D%0AMike">
Schedule Meeting
</a>
<!-- No recipient (compose new email) -->
<a href="mailto:?subject=Check%20this%20out&body=I%20found%20this%20interesting%3A%0D%0A">
Share via Email
</a>Notice that special characters like spaces, commas, and newlines are URL-encoded (%20, %2C, %0D%0A). The last example shows how to create a "share" link with no recipient—the user fills in who to send it to.
Manually encoding URLs is error-prone. Let's look at how to build mailto URLs programmatically with proper encoding.
URL Encoding
When building mailto URLs dynamically, you need to properly encode special characters. Use encodeURIComponent rather than URLSearchParams: the latter encodes spaces as +, which RFC 6068 says should not be used in mailto URIs because a + cannot be told apart from a real plus sign.
// Build mailto URL with proper encoding
function buildMailtoUrl(options) {
const { to, cc, bcc, subject, body } = options;
// Start with recipient
let mailto = 'mailto:' + (to || '');
// Build query parameters with encodeURIComponent:
// RFC 6068 says spaces SHOULD be %20 (not +) and
// line breaks MUST be %0D%0A
const params = [];
if (cc) params.push('cc=' + encodeURIComponent(cc));
if (bcc) params.push('bcc=' + encodeURIComponent(bcc));
if (subject) params.push('subject=' + encodeURIComponent(subject));
if (body) params.push('body=' + encodeURIComponent(body.replace(/\r?\n/g, '\r\n')));
// Append parameters
if (params.length) {
mailto += '?' + params.join('&');
}
return mailto;
}
// Usage
const mailto = buildMailtoUrl({
to: 'support@example.com',
subject: 'Help with my order #12345',
body: 'Hi,\n\nI need help with my order.\n\nOrder ID: 12345\nIssue: Item damaged\n\nThanks!'
});
// Result:
// mailto:support@example.com?subject=Help%20with%20my%20order%20%2312345&body=Hi%2C%0D%0A%0D%0AI%20need%20help%20with%20my%20order.%0D%0A%0D%0AOrder%20ID%3A%2012345%0D%0AIssue%3A%20Item%20damaged%0D%0A%0D%0AThanks!
// Note: URLSearchParams would produce + for spaces; RFC 6068
// advises against that because "+" is ambiguous in mailto URIsThe buildMailtoUrl function above handles all the encoding automatically. You pass plain text for the subject and body, and it produces a properly encoded URL. Spaces come out as %20 and line breaks as %0D%0A, as RFC 6068 requires.
One common challenge is formatting the email body with line breaks. Let's look at how to handle multiline content.
Multiline Body
Line breaks in mailto bodies require special handling. RFC 6068 says they MUST be encoded as %0D%0A (carriage return + line feed). encodeURIComponent turns \n into %0A, so join lines with \r\n to get %0D%0A.
// Line breaks in mailto body
// RFC 6068: line breaks MUST be %0D%0A (CRLF)
const body = 'Line 1%0D%0ALine 2%0D%0ALine 3';
const mailto = `mailto:?body=${body}`;
// With template literal
function createMailtoWithBody(to, subject, lines) {
const body = lines.join('\r\n');
const encoded = encodeURIComponent(body);
return `mailto:${to}?subject=${encodeURIComponent(subject)}&body=${encoded}`;
}
// Usage
const mailto = createMailtoWithBody(
'support@example.com',
'Bug Report',
[
'Bug Description:',
'',
'Steps to Reproduce:',
'1. Go to...',
'2. Click...',
'3. Observe...',
'',
'Expected: ...',
'Actual: ...'
]
);The createMailtoWithBody function takes an array of lines and joins them with newlines before encoding. This makes it easy to create structured templates like bug reports or support requests with proper formatting.
For React applications, you'll want a reusable component that handles all this complexity internally.
React Component
This React component encapsulates mailto URL generation, letting you use simple props for recipient, subject, and body while handling all encoding automatically.
// Mailto link component
function MailtoLink({ to, cc, bcc, subject, body, children, ...props }) {
const buildHref = () => {
// encodeURIComponent, not URLSearchParams (which turns spaces into +)
const params = [];
if (cc) params.push('cc=' + encodeURIComponent(cc));
if (bcc) params.push('bcc=' + encodeURIComponent(bcc));
if (subject) params.push('subject=' + encodeURIComponent(subject));
if (body) params.push('body=' + encodeURIComponent(body.replace(/\r?\n/g, '\r\n')));
const queryString = params.join('&');
return `mailto:${to || ''}${queryString ? '?' + queryString : ''}`;
};
return (
<a href={buildHref()} {...props}>
{children}
</a>
);
}
// Usage
<MailtoLink
to="sales@example.com"
subject="Product Inquiry"
body={`Hi,
I'm interested in learning more about your product.
Name: [Your name]
Company: [Your company]
`}
>
Contact Sales
</MailtoLink>The MailtoLink component accepts all standard mailto parameters as props and passes through any additional HTML attributes. You can include multiline body text using template literals, and the component handles encoding automatically.