Send email with Next.js and Sendgrid
In this tutorial we will create a contact form where user will be able to fill the form and upon submission an email will be sent to us containing the data provided by the user using sendgrid.
First we will create a next.js app. Open terminal in desired directory and run
npx create-next-app your-app-name
Once its done, open this app in code editor, go to terminal again and run
npm install dotenv @sendgrid/mail
Now go to Sendgrid create an account or login. Once you are logged in, you will redirected to dashboard page. From the left side bar click on Settings and then click API Keys. Click Create API Key provide name of your choice and then click Create & View.
Copy the API key, you will never see it again. Goto your code editor, create a .env file at the root level of your project and add
SG_API_KEY=paste-your-sendgrid-api-key-here
make sure to add .env file in .gitignore file so that if you push your code to github, .env file is not exposed. Go back to .env file and add
TO_EMAIL=enter-receving-email-id FROM_EMAIL=enter-sender-email-id
FROM_EMAIL should be the email id which you used to create account on sendgrid. TO_EMAIL will be the email id where you want to receive emails.
NOTE: Make sure TO_EMAIL is not hotmail. I was not able to receive email in my hotmail account so I used gmail.
Navigate to pages directory, inside pages directory, create a file contact.js and paste the following code
require("dotenv").config(); const sgMail = require("@sendgrid/mail"); const { SG_API_KEY, FROM_EMAIL, TO_EMAIL } = process.env; sgMail.setApiKey(SG_API_KEY); export default async function handler(req, res) { const { name, email, message } = req.body; const msg = { to: TO_EMAIL, // Change to your recipient from: FROM_EMAIL, // Change to your verified sender subject: "Contact", html: `<p><strong>name: </strong>${name}</p> <p><strong>email: </strong>${email}</p> <p><strong>message: </strong>${message}</p>`, }; await sgMail.send(msg); console.log("email sent"); res.status(200).json({ success: true }); }
At the top we imported dotenv and @sendgrid/mail packages which we installed earlier. After that we destructured SG_API_KEY, FROM_EMAIL and TO_EMAIL from process.env
Next we have called setApiKey method on sgMail and passed our sendgrid api key as argument.
Finally we defined an asynchronous function handler which takes request and response as arguments.
From our frontend, for this tutorial we will send data containing three fields name, email and message, so we destructured all of them from req.body. After that we defined an object msg, subject key will be what we see in our email's subject and html field will be the email body.
Now its time to send an email which we did by calling send method on sgMail and passed msg object as argument.
Now goto pages/index.js and paste the following code
import { useState } from "react"; export default function Home() { const [values, setValues] = useState({ name: "", email: "", message: "", }); const { name, email, message } = values; const handleChange = (e) => setValues({ ...values, [e.target.name]: e.target.value }); const handleSubmit = async (e) => { e.preventDefault(); await fetch("http://localhost:3000/api/hello", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(values), }); }; return ( <> <h2>Next.js Sendgrid form submission</h2> <div className="container"> <form onSubmit={handleSubmit}> <h3>Contact Form</h3> <div className="input_container"> <input type="text" name="name" value={name} onChange={handleChange} placeholder="Enter your name..." className="input" /> </div> <div className="input_container"> <input type="email" name="email" value={email} onChange={handleChange} placeholder="Enter your email..." className="input" /> </div> <div className="input_container"> <textarea name="message" value={message} onChange={handleChange} placeholder="Enter your message..." className="input" /> </div> <div className="btn_container"> <button>Send</button> </div> </form> </div> </> ); }
In this file we are displaying a form. We have initialized state to hold name, email and message values. After that handleChange function which will capture user input and set the value in state and finally handleSubmit function which is an asynchronous function to submit the form.
In handleSubmit function, we are making a POST request to /api/contact route and passing the data in string form which will be received by handler function in /api/contact.js file which will take the data and send email containing that data.
Finally lets add some styling
html, body { padding: 0; margin: 0; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; background: #eee; } a { color: inherit; text-decoration: none; } * { box-sizing: border-box; } .container { max-width: 400px; margin: 0 auto; padding: 20px; background: white; border-radius: 10px; box-shadow: 1px 2px 3px #ddd; } h2, h3 { text-align: center; } .input_container { margin-bottom: 20px; } .input { width: 100%; padding: 5px; outline: none; } .btn_container { text-align: center; } button { background: #333; color: white; padding: 5px 10px; border-radius: 5px; outline: none; font-size: 16px; }
Now give it a try, in terminal type
npm run dev
So, that's how we can send email with Next.js and Sendgrid.