Email communication is an essential part of web applications. The ability to quickly and easily initiate an email from a web page provides a convenient way for users to get in touch, provide feedback, or request information.
JavaScript offers a simple way to open the user‘s default email client with a pre-populated email address through the "mailto" protocol. In this comprehensive guide, we‘ll explore the ins and outs of using mailto in JavaScript.
An Overview of Mailto
The mailto link allows you to create a clickable link on your web page that will open up the visitor‘s email client with specific information already filled in. This saves the user from having to manually open their email, compose a new message, and enter the recipient‘s email address.
Some key things that mailto allows you to do:
- Pre-fill the recipient‘s email address
- Pre-fill a subject line
- Pre-fill a body message
- Pre-fill CC and BCC recipients
- Pre-populate fields needed to attach a file
Browser support for mailto is excellent. All major browsers have supported the protocol for decades. Mailto works perfectly well on both desktop and mobile.
The one downside of mailto is that it relies on the user having an email client installed. For most users this isn‘t a problem, but it does mean mailto won‘t work on every device.
Overall, mailto is a great way to streamline email communication from your web pages. Let‘s look at how we can leverage it in JavaScript.
Using Mailto in JavaScript
There are a two common approaches to use mailto in JavaScript:
- Dynamically create an anchor tag with href set to a mailto link
- Set
window.location.hrefdirectly to a mailto link
Let‘s explore both methods.
Method 1: Create a Mailto Anchor Tag
We can utilize mailto by creating an anchor (<a>) tag in JavaScript and setting the href attribute to a mailto link:
// Create anchor element
const mailLink = document.createElement(‘a‘);
// Construct mailto URL
const mailtoString = ‘mailto:name@example.com‘ +
‘?subject=Example%20Subject‘ +
‘&body=Message%20body%20goes%20here‘;
// Set anchor href to mailto URL
mailLink.href = mailtoString;
// Click the anchor to open email
mailLink.click();
Here‘s what‘s happening in the code above:
-
We dynamically create an
<a>anchor tag usingdocument.createElement(). This tag will serve as our mailto link. -
We construct a mailto URL string that includes the email recipient, subject, and body message. Note that spaces need to be URL encoded as
%20. -
We set the
hrefproperty of the anchor tag to our mailtoString. This turns the anchor into a clickable mailto link. -
Using
mailLink.click()simulates a click on the link, which opens the user‘s email client.
And that‘s all there is to it! The mailto protocol handles the rest.
One thing to keep in mind is that mailLink.click() will only work during a legitimate click handler like onclick. If you try to trigger a click outside of an event, the browser will block it.
Here is a full example of attaching our mailto link to a clickable button:
<!-- HTML -->
<button id="mail-button">Contact Us</button>
<script>
// JavaScript
const button = document.getElementById(‘mail-button‘);
button.addEventListener(‘click‘, () => {
const mailLink = document.createElement(‘a‘);
mailLink.href = "mailto:name@example.com?subject=Feedback";
mailLink.click();
});
</script>
Now when users click the "Contact Us" button, it will open up a new pre-filled email. The mailto link handles the heavy lifting for us.
Method 2: Set window.location.href to a Mailto Link
The second approach we can use is setting window.location.href directly to a mailto string:
// Construct mailto URL
const mailtoString = ‘mailto:name@example.com‘ +
‘?subject=Example%20Subject‘ +
‘&body=Message%20body%20goes%20here‘;
// Set window URL to open email
window.location.href = mailtoString;
By setting window.location.href (the current page URL) to a mailto string, the browser will attempt to open the user‘s email client.
We can easily attach this to an event handler:
contactButton.addEventListener(‘click‘, () => {
const mailString = "mailto:test@example.com";
window.location.href = mailString;
});
Now clicking the button will again initiate a pre-filled email.
The benefit of this approach is simplicity – we don‘t have to bother creating anchor elements in JavaScript. But the downside is less flexibility if we ever want to customize the functionality.
Comparing the Two Approaches
Let‘s summarize the pros and cons of each method:
Anchor Element Approach
Pros:
- More customizable – can manipulate the anchor using JS
- Can simulate clicks programatically
- Arguably more semantic
Cons:
- Slightly more complex code
window.location.href Approach
Pros:
- Simple one-liner to open email
- Easy to implement
Cons:
- Less flexibility for custom behavior
- Less semantic
So in summary, the anchor element method involves slightly more code, but enables more customization. And the window.location.href approach trades flexibility for simplicity.
Choose whichever pattern better suits your needs!
Composing the Mailto Link
Now that we‘ve looked at techniques to activate mailto behavior, let‘s turn our attention to constructing the mailto URL itself.
A typical mailto link looks like this:
mailto:someone@example.com?subject=Feedback&body=Message%20text
Breaking it down piece by piece:
mailto:– The mailto protocol prefixsomeone@example.com– The email recipientsubject=Feedback– Pre-filled subject linebody=Message%20text– Pre-filled message body
We can also optionally include CC, BCC, and attachments:
mailto:someone@example.com?cc=cc@example.com&bcc=bcc@example.com&body=Message&attachment=file.zip
Let‘s look at some examples of constructing mailto links in JavaScript:
To:
const to = "someone@example.com";
Subject:
const subject = "?subject=" + encodeURIComponent("Hello There");
// Encode spaces and special characters
Body:
const body = "&body=" + encodeURIComponent("Message body content");
CC:
const cc = "&cc=" + encodeURIComponent("cc@example.org");
BCC:
const bcc = "&bcc=" + encodeURIComponent("bcc@example.org");
Attachment:
// Specify name and type
const attachment = "&attachment=file.pdf::application/pdf";
We can concatenate all the pieces together:
const mailToString = "mailto:" + to + subject + body + cc + bcc + attachment;
And now mailToString contains our full featured mailto link!
Mailto Link Generator Function
Since properly formatting mailto links requires some effort, it can be helpful to abstract the composition into a reusable function:
function generateMailto(to, subject, body, cc, bcc, attachment) {
// Element parameters
const mailto = "mailto:" + to;
const subjectLine = subject ? "?subject=" + encodeURIComponent(subject) : "";
const mailBody = body ? "&body=" + encodeURIComponent(body) : "";
const mailCC = cc ? "&cc=" + encodeURIComponent(cc) : "";
const mailBCC = bcc ? "&bcc=" + encodeURIComponent(bcc) : "";
const mailAttach = attachment ? "&attachment=" + attachment : "";
// Combine URL components
const mailtoString = mailto + subjectLine + mailBody + mailCC + mailBCC + mailAttach;
return mailtoString;
}
// Generate mailto link
const myMailto = generateMailto("test@example.com", "Hello", "My message");
Now we can easily compose mailto links by calling our generator function instead of concatenating strings ourselves. This helps tidy up our code.
Real World Examples
Now that we‘ve thoroughly covered the foundations, let‘s briefly showcase some real world use cases where mailto can provide value.
Contact Forms
Simplified contact forms can ditch server-side code and database storage by directly opening pre-filled emails for user messages:
contactButton.addEventListener(‘click‘, () => {
const mailto = generateMailto("help@example.com", "Website Help",
document.getElementById(‘message‘).value);
window.location.href = mailto;
});
Feedback Widgets
Web apps can allow users to quickly provide feedback via email by placing mailto links in their UI:
<a href="mailto:feedback@app.com?subject=App%20Feedback">
Give Feedback
</a>
Email Newsletter
Rather than build a subscription server, sites can capture signups directly in the reader‘s email client:
newsletterBtn.addEventListener(‘click‘, () => {
const mailto = generateMailto("newsletter@site.com", "Subscribe to Newsletter");
window.location.href = mailto;
});
These are just a few examples of how mailto can be leveraged to create quick email functionality without needing form processing on the server.
Browser Testing
Given mailto‘s reliance on the client‘s email environment, it‘s worth verifying behavior across browsers during testing.
Be sure to check:
- Default email client – What‘s the default experience for composing emails? Does this vary across browsers?
- Pre-filled fields – Are the "To", subject line, and body populating correctly?
- Encoded characters – Are encoded symbols and spaces decoding properly?
- CC and BCC – Do carbon copy and blind copy fields work as expected?
- Attachments – Can users successfully attach files to emails?
Cross-browser irregularities can be handled by feature detecting for mailto support and using alternate fallback methods if needed.
It‘s also wise to provide instructions to users if their device does not have an email client installed. This avoids dead ends from mailto links.
Overall though, the mailto protocol offers excellent cross-device support when properly implemented.
Limitations of Mailto
While mailto is ubiquitous and easy to use, there are still limitations to consider:
- Lack of email client – Mailto relies on having an email app installed, which isn‘t guaranteed on all devices.
- Client variability – The email experience can vary drastically across default clients.
- No JavaScript response – We don‘t know if the user actually sent the email successfully.
- Constraints on pre-filled content – Some email clients may impose restrictions.
- No open and click tracking – We can‘t track engagement beyond initial link clicks.
For these reasons, production contact forms still benefit from running through a web server rather than directly initiating emails. Server-side form handling enables better validation, deliverability, analytics, and spam filtering.
So in more advanced scenarios, mailto acts best as a supplement to traditional form workflows rather than a wholesale replacement.
Conclusion
The JavaScript mailto protocol delivers a straightforward way to kickstart email communication from our web pages.
We learned two approaches to activate mailto behavior:
- Creating anchor tags
- Setting
window.location.href
We also explored how to properly format mailto links with pre-filled content like subjects, messages, CC addresses, and attachments. And we covered real world use cases like contact forms, newsletter signups, and feedback widgets.
While mailto has limitations around client dependencies and tracking, it serves as an excellent convenience feature under the right circumstances.
To recap, here is a final code example demonstrating a reusable mailto link generator:
// Generate mailto link
function generateMailto(to, subject, body, cc, bcc, attachment) {
// Build components
const mailtoString = "mailto:" + to +
"?subject=" + encodeURIComponent(subject) +
"&body=" + encodeURIComponent(body) +
cc ? "&cc=" + encodeURIComponent(cc) : "" +
bcc ? "&bcc=" + encodeURIComponent(bcc) : "" +
attachment ? "&attachment=" + attachment : "";
return mailtoString;
}
// Example usage
const emailLink = generateMailto("hello@example.com", "Greetings!");
contactButton.addEventListener(‘click‘, () => {
window.location.href = emailLink;
});
So next time you need to connect site visitors directly with relevant email contacts, keep mailto in your JavaScript utility belt!


