AskHandle Blog
How Do I Send HTML Emails with Attachments Using Mailgun in Node.js?

How Do I Send HTML Emails with Attachments Using Mailgun in Node.js?
Sending HTML emails with attachments through Mailgun in Node.js is a common task that many developers need to handle in their applications. This article shows you the steps and best practices to send rich HTML content emails along with file attachments using the Mailgun SDK.
Setting Up Your Project
First, you need to install the required packages. The official Mailgun SDK for Node.js is the recommended way to interact with the Mailgun API. Open your terminal and run:
1npm install mailgun.js form-dataThe form-data package is needed because Mailgun SDK depends on it for handling multipart form data, which is used when sending attachments.
Basic Configuration
Create a new file in your project and import the required modules. You'll need your Mailgun API key and domain name from your Mailgun dashboard:
1const formData = require('form-data');
2const Mailgun = require('mailgun.js');
3const mailgun = new Mailgun(formData);
4
5const mg = mailgun.client({
6 username: 'api',
7 key: 'your-api-key-here'
8});Creating HTML Email Content
When sending HTML emails, it's good practice to include both HTML and plain text versions. This ensures your email is readable even if the recipient's email client doesn't support HTML:
1const htmlContent = `
2 <html>
3 <body>
4 <h1>Welcome to Our Newsletter</h1>
5 <p>This is a sample HTML email with <strong>formatted text</strong>.</p>
6 </body>
7 </html>
8`;
9
10const plainText = 'Welcome to Our Newsletter. This is a sample email with formatted text.';Adding Attachments
You can attach files to your email using the attachment parameter. Here's how to attach files from your local system:
1const fs = require('fs');
2
3const attachmentData = {
4 data: fs.readFileSync('/path/to/file.pdf'),
5 filename: 'document.pdf'
6};Sending the Email
Now you can combine all elements to send your HTML email with attachments:
1async function sendEmailWithAttachment() {
2 try {
3 const messageData = {
4 from: 'Your Name <sender@yourdomain.com>',
5 to: 'recipient@example.com',
6 subject: 'HTML Email with Attachment',
7 html: htmlContent,
8 text: plainText,
9 attachment: attachmentData
10 };
11
12 const response = await mg.messages.create('your-domain.com', messageData);
13 console.log('Email sent successfully:', response);
14 } catch (error) {
15 console.error('Error sending email:', error);
16 }
17}Error Handling and Best Practices
Always implement proper error handling when sending emails. Some key points to consider:
- Check file sizes before attaching them. Mailgun has limits on attachment sizes.
- Validate email addresses before sending.
- Use try-catch blocks to handle potential errors gracefully.
- Monitor your sending rates to stay within Mailgun's limits.
Here's an example with enhanced error handling:
1function validateEmailAddress(email) {
2 const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
3 return regex.test(email);
4}
5
6async function sendEmailWithValidation(recipientEmail) {
7 if (!validateEmailAddress(recipientEmail)) {
8 throw new Error('Invalid email address');
9 }
10
11 const fileStats = fs.statSync('/path/to/file.pdf');
12 const fileSizeInMB = fileStats.size / (1024 * 1024);
13
14 if (fileSizeInMB > 25) {
15 throw new Error('File size exceeds 25MB limit');
16 }
17
18 // Proceed with sending email...
19}Testing Your Implementation
Before sending emails to real users, test your implementation thoroughly. Mailgun provides a sandbox domain for testing purposes. Use this domain to verify that your HTML renders correctly and attachments are working as expected.
You can also set up event webhooks in your Mailgun dashboard to track email delivery status, opens, clicks, and other metrics