Sendgrid
Send email to a user
This snippet sends a transactional email through SendGrid from a Next.js serverless API route. It is the backend behind a contact form, when a visitor submits their email, the route fires off a styled HTML "thanks for reaching out" reply to them. Because it runs on the server, the SendGrid API key stays out of the browser, which is exactly where a mail-sending credential needs to be.
API call
import sendgrid from "@sendgrid/mail";
sendgrid.setApiKey(process.env.SENDGRID_API_KEY);
export default async (req, res) => {
try {
await sendgrid.send({
to: req.body.email,
from: "rodriguescarsonwork@gmail.com",
subject: "Greetings! Thankyou for contacting me",
html: `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en">
<head>
<meta charset="utf-8">
<title>The HTML5 Herald</title>
<meta name="description" content="The HTML5 Herald">
<meta name="author" content="SitePoint">
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />
<link rel="stylesheet" href="css/styles.css?v=1.0">
</head>
<body>
<div className="img-container" style="display: flex;justify-content: center;align-items: center;border-radius: 5px;overflow: hidden; font-family: 'helvetica', 'ui-sans';">
</div>
<div className="container" style="margin-left: 20px;margin-right: 20px;">
<h3>Hello, ${req.body.email} 👋</h3>
<div style="font-size: 16px;">
<p>Thankyou for contacting me through my website. I'm excited to work with you.</p>
<p><span className="spantext" style="font-weight: bold;">Reply</span> to this email with your requirements and I will get back to you.</p>
<p>Meanwhile, <a className="blog" href="https://carsonrodrigues.com/blog/" style="text-decoration: none;color: blue;font-weight: bold;">checkout my blog</a> to get more insights about my work.</p>
<p>Or simply, just say Hi :) <a href="https://wa.me/917020286635?text=Hi" target="__blank" className="whatsapp" style="text-decoration: none;font-weight: bold;background: #10B981;padding: 4px;border-radius: 5px;color: white;">WhatsApp</a></p>
<br>
</div>
<img src="https://carsonrodrigues.com/logo.png" className="logo-image" style="height: 50px;width: 50px;border-radius: 5px;overflow: hidden;">
<p className="footer" style="font-size: 16px;padding-bottom: 20px;border-bottom: 1px solid #D1D5DB;">Regards<br>Carson Rodrigues<br>Software Developer<br>+91 7020286635</p>
<div class="footer-links" style="display: flex;justify-content: center;align-items: center;">
<a href="https://carsonrodrigues.com/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">Website</a>
<a href="https://carsonrodrigues.com/blog/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">Blog</a>
<a href="https://github.com/rodriguescarson/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">GitHub</a>
<a href="https://instagram.com/maninthere/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">Instagram</a>
<a href="https://linkedin.com/in/rodriguescarson/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">LinkedIn</a>
<a href="https://x.com/carsonmarz/" style="text-decoration: none;margin: 8px;color: #9CA3AF;">Twitter</a>
</div>
</div>
</body>
</html>`,
});
} catch (error) {
return res.status(error.statusCode || 500).json({ error: error.message });
}
return res.status(200).json({ error: "" });
};
NOTE:
- Replace
fromfield to your email - Replace
tofield to the email of the person you want to send the email to - In the
htmlandsubjectfield, insert your custom text - If you don't want to use HTML, change
htmltotextand write the desired text.
Usage
Create an account on Sendgrid
Authenticate sender
Sendgrid requires you to authenticate yourself (email account) which you want the emails to be sent from. For that they have clearly mentioned instructions.
- Go to Sender Authentication page.
- Create a new sender.
- Fill out the form with all your details.
- Verify by checking your mail and clicking on Verify button.
Set environment variable
In your .env file, create an entry for SENDGRID_API_KEY and paste the credentials you retrieved from the sendgrid portal.
NOTE: DO NOT push this file to GitHub.
Install @sendgrid/mail node package
npm install @sendgrid/mail- We use two methods from the package:
sendgrid.setApiKey()andsendgrid.send()
A live demo of this API can be found on my homepage. I've used Sendgrid on my Contact component on the Home Page and Blog page.
How it works
The handler is a single serverless function. At module load it calls sendgrid.setApiKey(process.env.SENDGRID_API_KEY) so the key comes from the environment rather than the source. On each request it awaits sendgrid.send() with four fields, to (taken from req.body.email, the address the visitor submitted), a fixed from address, a subject, and an html body. The HTML is a full email document, and it interpolates ${req.body.email} into the greeting so the message is personalized. The whole send is wrapped in a try/catch: on failure it responds with error.statusCode || 500 and the error message, and on success it returns a 200 with an empty error string. Because everything runs server-side, the SendGrid key is never exposed to the client.
Notes & gotchas
- Keep
SENDGRID_API_KEYin an environment variable and never commit it. A leaked key lets anyone send mail as you, so rotate it immediately if it ends up in git. - The
fromaddress must be a verified sender (or verified domain) in SendGrid, as covered in the sender authentication step above. Sending from an unverified address will be rejected. Domain authentication (SPF/DKIM) improves deliverability and keeps messages out of spam. - This route trusts
req.body.emaildirectly as both the recipient and the greeting text. Validate and sanitize that input, an attacker could otherwise use your endpoint to send mail to arbitrary addresses (open relay abuse) or inject content. Add rate limiting and, on a public contact form, a spam/bot check such as a CAPTCHA. - Inline all CSS in HTML emails, as this template does, since most email clients strip
<style>/external stylesheets. The<link rel="stylesheet">here will not apply in mail clients, the styles that matter are the inlinestyle="..."attributes. classNameis React syntax and is ignored in raw email HTML, useclassfor any styling hooks you actually rely on.- For higher volume or templated content, consider SendGrid Dynamic Templates instead of hand-built HTML strings.