Create and Deploy a SendGrid-Powered Next.js and Node.js Contact Form with ZEIT Now
Create a SendGrid-Powered Next.js and Node.js Contact Form and deploy it with ZEIT Now.
SendGrid is a cloud-based SMTP provider that allows you to send email without having to maintain email servers.
This guide walks you through creating a Next.js app with a contact form powered by SendGrid, and how to deploy it with ZEIT Now.
Step 1: Creating a SendGrid API Key
To start, you need to have created a SendGrid account. Once logged in to SendGrid, follow the setup guide steps for integrating using the Web API, choosing the Node.js option.
You will be asked to supply a name for your API key and given the option to create it.
Once created, make a note of this API key as it will not be shown again, this will be used in the app you create.
Step 2: Creating Your Next.js App
Get started creating your Next.js app by making a project directory with the required structure and moving into it:
mkdir -p nextjs-sendgrid/pages/api && cd nextjs-sendgrid
Next, initialize the project:
npm init -y
Continue to install the SendGrid Node.js helper which allows you to send email using your API key, along with the required dependencies for Next.js including dotenv
for using your API key during local development:
npm i @sendgrid/mail dotenv next react react-dom
Inside of the /pages
directory, create an index.js
file with the code below:
import React, { useState } from 'react' export default () => { const [status, setStatus] = useState({ submitted: false, submitting: false, info: { error: false, msg: null } }) const [inputs, setInputs] = useState({ email: '', message: '' }) const handleResponse = (status, msg) => { if (status === 200) { setStatus({ submitted: true, submitting: false, info: { error: false, msg: msg } }) setInputs({ email: '', message: '' }) } else { setStatus({ info: { error: true, msg: msg } }) } } const handleOnChange = e => { e.persist() setInputs(prev => ({ ...prev, [e.target.id]: e.target.value })) setStatus({ submitted: false, submitting: false, info: { error: false, msg: null } }) } const handleOnSubmit = async e => { e.preventDefault() setStatus(prevStatus => ({ ...prevStatus, submitting: true })) const res = await fetch('/api/send', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(inputs) }) const text = await res.text() handleResponse(res.status, text) } return ( <main> <form onSubmit={handleOnSubmit}> <label htmlFor="email">Email</label> <input id="email" type="email" onChange={handleOnChange} required value={inputs.email} /> <label htmlFor="message">Message</label> <textarea id="message" onChange={handleOnChange} required value={inputs.message} /> <button type="submit" disabled={status.submitting}> {!status.submitting ? !status.submitted ? 'Submit' : 'Submitted' : 'Submitting...'} </button> </form> {status.info.error && ( <div className="error">Error: {status.info.msg}</div> )} {!status.info.error && status.info.msg && ( <div className="success">{status.info.msg}</div> )} </main> ) }
Add development and build scripts to the package.json
file. These allow you to run your app with a development server and tell ZEIT Now how to build your project for deployment:
{ ... "scripts": { "dev": "next dev", "build": "next build" } }
Step 3: Writing the Serverless Function
Create the Node.js API endpoint that will be used to send the form data to the SendGrid API by adding a send.js
file to the /pages/api
directory with the following code:
const sgMail = require('@sendgrid/mail') export default async function(req, res) { sgMail.setApiKey(process.env.SENDGRID_API_KEY) const { email, message } = req.body const content = { to: '[your-email-address]', from: email, subject: `New Message From - ${email}`, text: message, html: `<p>${message}</p>` } try { await sgMail.send(content) res.status(200).send('Message sent successfully.') } catch (error) { console.log('ERROR', error) res.status(400).send('Message not sent.') } }
to
value to the required destination for emails sent.Create a .env
file, adding your SendGrid API key where prompted:
SENDGRID_API_KEY=[your-sendgrid-api-key]
Add a next.config.js
file that will provide your app with the defined environment variable:
require('dotenv').config() module.exports = { env: { SENDGRID_API_KEY: process.env.SENDGRID_API_KEY } }
npm run dev
.Create a Now Secret to securely store the SendGrid API key, this will be used when deploying the app with ZEIT Now.
now secrets add SENDGRID_API_KEY [your-sendgrid-api-key]
Lastly, to make the Now Secret available to the Serverless Function when deployed, create a now.json
file:
{ "build": { "env": { "SENDGRID_API_KEY": "@sendgrid_api_key" } } }
Step 4: Deploying the App with ZEIT Now
With the project complete, you are ready to deploy it with ZEIT Now.
If you have not yet installed Now, you can do so by installing Now CLI.
You can now deploy the project with a single command:
now
To deploy your Next.js, Node.js, and SendGrid project from a Git repository, you can use either Now for GitHub or Now for GitLab to have your project automatically deployed on every push, and the production domain updated on push to master.