How to trigger an email on event confirmation with Netlify
Tags: jamstack, serverless, nextjs, react
Published: 2022-11-24 07:31:05

---
title: How to trigger an email on event confirmation with Netlify
published: true
description: Learn how to quickly build an event confirmation application with Netlify, Xata, SendGrid, and Cloudinary using Next.js
tags: #jamstack #serverless #nextjs #react
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kuuxigfb6gcvxxs714vl.png
# Use a ratio of 100:42 for best results.
# published_at: 2022-11-23 20:19 +0000
---
Over the years, emails have been the go-to medium for developers to send event RSVPs, authentication codes, and application runtime notifications, among others. The implementation process is also daunting for developers as they need to cater to the adopted mail provider and deployment mechanism.

In this post, we will learn how to quickly build an event confirmation application with Netlify, Xata, SendGrid, and Cloudinary using Next.js.

## Technology overview

[Netlify](https://www.netlify.com/) is a platform for deploying and building highly-performant and dynamic websites, e-commerce stores, and web applications.

[Xata](https://xata.io/?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog) is an HTTP API-based serverless database for building scalable applications. It supports a built-in search engine, branching, scalability, and durability without manually managing database configuration and deployment.

[SendGrid](https://sendgrid.com/) is a cloud-based email marketing tool developers and marketers use to manage mailing lists, A/B testing, predefined templates, and image libraries used in campaign management and audience engagement.

[Cloudinary](https://cloudinary.com/?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog) is a visual media service for uploading, storing, managing, transforming, and delivering images and videos for websites and applications. 

## GitHub and Deployment link

The project source codes and deployment link are below:

- [GitHub link](https://github.com/Mr-Malomz/event-confirmation)
- [Live Site](https://unique-hamster-b28145.netlify.app/)

## Prerequisites 

To follow along with this tutorial, the following requirements apply:

- Basic understanding of JavaScript and React
- A [Netlify](https://www.netlify.com) account for managing deployment. [**Signup**](https://app.netlify.com/signup?_ga=2.194596141.1083651187.1647633137-873794739.1647633137) **is completely free**
- A [Xata account](https://xata.io/?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog) for storing data. [**Signup**](https://app.xata.io/signin?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog) **is completely free**
- A [Github account](https://github.com) for saving source code. [**Signup**](https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F&source=header-home) **is completely free**.
- A [SendGrid account](https://sendgrid.com/) for sending emails, [**Signup**](https://signup.sendgrid.com/) for a trial account is completely free


## Getting started

We need to create a Next.js starter project by navigating to the desired directory and running the command below in our terminal.

```bash
npx create-next-app event-confirmation && cd event-confirmation
```

The command creates a Next.js project called `event-confirmation` and navigates into the project directory.

**Installing TailwindCSS and Node-Fetch**
[TailwindCSS](https://tailwindcss.com/) is a utility-first CSS framework packed with classes to help us style our web pages. To use it in our application, run the command below:

```bash
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
```

The command installs TailwindCSS and its dependencies and generates  `tailwind.config.js` and `postcss.config.js` files.

Next, we need to update `tailwind.config.js` file with the snippet below:

```js
module.exports = {
  content: [
    './app/**/*.{js,ts,jsx,tsx}',
    './pages/**/*.{js,ts,jsx,tsx}',
    './components/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```
Finally, we need to add TailwindCSS directives to our application. The directives give our application access to TailwindCSS utility classes. To do this, navigate to the `styles` folder and update the `globals.css` files in it with the snippet below:

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

Lastly, we need to install `node-fetch`, a package for making HTTP requests. To do this, we need to run the command below:

```bash
npm i node-fetch
```

## Set up a Database on Xata

To create a database for storing our event confirmation data, we need to log into our Xata’s workspace, click the **Add a Database** button, input `events` as the database name, and **Create**.

![Add a Database](https://paper-attachments.dropboxusercontent.com/s_A1144B74EC1072093F0D2701A540D1E74AD827D7B0FFCD60C26EE8B5BA462734_1667173516275_Screenshot+2022-10-31+at+00.44.55.png)
![input database name](https://paper-attachments.dropboxusercontent.com/s_FCD9D830F6428F1CD109C3FE7FBEC3248DA8EAC260696449A52E25A8B5E7846C_1667521568046_Screenshot+2022-11-04+at+01.25.52.png)


Next, we need to create a table in our database. To do this, click the **Start from scratch** menu, input `confirmed` as the table name, and **Add table**.

![click the start from scratch](https://paper-attachments.dropboxusercontent.com/s_FCD9D830F6428F1CD109C3FE7FBEC3248DA8EAC260696449A52E25A8B5E7846C_1667522004432_Screenshot+2022-11-03+at+11.47.48.png)
![input and create](https://paper-attachments.dropboxusercontent.com/s_FCD9D830F6428F1CD109C3FE7FBEC3248DA8EAC260696449A52E25A8B5E7846C_1667522018922_Screenshot+2022-11-03+at+11.48.16.png)


**PS**: *Xata auto-generates an ID column (a unique identifier) for our table.*

With that done, we need to add a `name` of type **String** and `email` of type **Email** columns to our table. To do this, click on the **Plus icon**, select type accordingly, input column name, and **Create column**.

![plus icon](https://paper-attachments.dropboxusercontent.com/s_FCD9D830F6428F1CD109C3FE7FBEC3248DA8EAC260696449A52E25A8B5E7846C_1667522519099_Screenshot+2022-10-29+at+16.31.54+copy.png)
![select string](https://paper-attachments.dropboxusercontent.com/s_A1144B74EC1072093F0D2701A540D1E74AD827D7B0FFCD60C26EE8B5BA462734_1667174472131_Screenshot+2022-10-31+at+01.00.47.png)
![input name](https://paper-attachments.dropboxusercontent.com/s_A1144B74EC1072093F0D2701A540D1E74AD827D7B0FFCD60C26EE8B5BA462734_1667174553609_Screenshot+2022-10-31+at+01.02.02.png)


After creating the columns, our updated table should be similar to the screenshot below:

![updated table](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667647164393_Screenshot+2022-11-05+at+12.18.38.png)


**Get Database URL and set up API Key**
By default, Xata provides a unique and secure URL for accessing the database. To get our database URL, click the **Get code snippet** button, copy the URL, and then click the **Set up API key** button to generate API key. We need the API key for authentication when using the database.

![Get code snippet](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667647181084_Screenshot+2022-11-05+at+12.18.45.png)



![URL and Set up API key](https://paper-attachments.dropboxusercontent.com/s_A1144B74EC1072093F0D2701A540D1E74AD827D7B0FFCD60C26EE8B5BA462734_1667175618585_Screenshot+2022-10-29+at+16.40.21.png)


**PS**: *The URL we need to copy starts from the* `*https://……*` *section*

Click the **Add a key** button, input `xata-function` as the name, and **Save**.

![Add a key](https://paper-attachments.dropboxusercontent.com/s_A1144B74EC1072093F0D2701A540D1E74AD827D7B0FFCD60C26EE8B5BA462734_1667175790072_Screenshot+2022-10-29+at+16.42.41.png)
![Copy API Key](https://paper-attachments.dropboxusercontent.com/s_A1144B74EC1072093F0D2701A540D1E74AD827D7B0FFCD60C26EE8B5BA462734_1667175790087_Screenshot+2022-10-29+at+16.46.22.png)


Both the URL and API key will come in handy when deploying our application.


## Set up SendGrid as an email provider

To get started, we need to log into our Sendgrid account and create a sender identity for sending emails. To do this, click the **Create a Single Sender** button and fill in the required details.

![Click on single sender](https://paper-attachments.dropboxusercontent.com/s_D82BCAF4FA806DDC66086296DB729575AF10BA7E5A187F3ABEBD28438E2912BE_1666296398440_Screenshot+2022-10-19+at+11.47.25.png)
![Fill details](https://paper-attachments.dropboxusercontent.com/s_D82BCAF4FA806DDC66086296DB729575AF10BA7E5A187F3ABEBD28438E2912BE_1666296483446_Screenshot+2022-10-19+at+11.50.25.png)


**PS**: *We will also be required to verify the email filled in as the sender's identity.*

Next, we need to create an API Key to securely access our SendGrid account and send emails from a client. To do this, navigate to the **API Key** tab under the **Settings** menu and click the **Create API Key** button.

![Create API Key](https://paper-attachments.dropboxusercontent.com/s_D82BCAF4FA806DDC66086296DB729575AF10BA7E5A187F3ABEBD28438E2912BE_1666296749691_Screenshot+2022-10-19+at+11.56.26.png)


Input `event-conf` as the API Key Name and click the **Create & View** button.


![Input detail and create](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667607808891_Screenshot+2022-11-05+at+01.23.06.png)


SendGrid will generate an API Key. We also need to copy and keep the generated key, as it will come in handy later on.

## Building the event confirmation application

**Create email template**
To get started, we need to create a reusable template for sending the event confirmation email to our users. To do this, first, we need to create an `emails` folder in the root directory, and in this folder create another folder `confirmed`.

![folder structure](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667643524056_Screenshot+2022-11-05+at+11.16.05.png)


Lastly, we need to create an `index.html` file inside the `confirmed` folder and add the snippet below:

```html
<html>
    <body
        style="
            font-family: 'Open Sans', 'Helvetica Neue', sans-serif;
            margin: 0 auto;
        "
    >
        <div
            style="
                background-color: white;
                display: inline-block;
                text-align: center;
                padding: 10px;
            "
        >
            <img
                style="height: 200px; width: 100vw"
                src="https://res.cloudinary.com/dtgbzmpca/image/upload/v1667575091/photo-1498931299472-f7a63a5a1cfa.jpg"
                alt="mars"
            />
            <h1>Welcome, {{name}}</h1>
            <p>
                We promised this will be the best sessions you have ever
                experienced!
            </p>
            <p>Thanks for subscribing!</p>
        </div>
    </body>
</html>
```

The snippet above creates and styles a template by using an optimized image hosted on Cloudinary as the template header and accepts a `name` variable to personalize the registered user’s name.

**Create Serverless Function**
With that done, we need to create a function that saves the details of interested users on Xata and sends a confirmation email. To get started; first, we need to create a `netlify` folder and create a `functions` folder in this folder.

![Updated folder](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667644802546_Screenshot+2022-11-05+at+11.39.43.png)


Secondly, we need to create a `saveandconfirm.js` file inside the `functions` folder and add the snippet below:

```js
import fetch from 'node-fetch';

exports.handler = async function (event, context, callback) {
    let bodyRequest = JSON.parse(event.body);
    const body = {
        name: bodyRequest.name,
        email: bodyRequest.email,
    };

    //save user on the database
    await fetch(`${process.env.XATA_URL}:main/tables/confirmed/data`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${process.env.XATA_API_KEY}`,
        },
        body: JSON.stringify(body),
    });

    //send confirmation email
    await fetch(`${process.env.URL}/.netlify/functions/emails/confirmed`, {
        headers: {
            'netlify-emails-secret': process.env.NETLIFY_EMAILS_SECRET,
        },
        method: 'POST',
        body: JSON.stringify({
            from: process.env.SEND_FROM_EMAIL,
            to: body.email,
            subject: "You've been confirmed!",
            parameters: {
                name: body.name,
            },
        }),
    });

    return {
        statusCode: 200,
        body: JSON.stringify({ data: 'Email confirmation sent successfully!' }),
    };
};
```

The snippet above does the following:

- Imports the required dependency 
- **Line****s** **4-8**: Gets the request body 
- **Line****s** **11-18**: Creates a `POST` request to the Xata database by passing the URL as an environment variable with the database details and API key
- **Line****s** **21-34**: Creates a `POST` request that sends a request with the required parameters to the email handler and creates the email body
- **Lines 36-39**: Returns the appropriate response.

We also constructed the Xata database URL by passing in the **branch**, **table name**, and **endpoint type**.

```bash
process.env.XATA_URL:<BRANCH NAME>/tables/<TABLE NAME>/ENDPOINT TYPE
```

We can get the required details from our workspace

![Branch name and Table name](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667647088481_Screenshot+2022-11-05+at+12.17.30.png)


In our case, we filled it using an environment variable. We will add it when deploying our application to Netlify. An adequately filled  URL is below:

```bash
process.env.XATA_URL:main/tables/userDetails/data
```

Similarly, we appended our email directory `confirmed` to the email handler as shown below:

```bash
process.env.URL/.netlify/functions/emails/confirmed
```

Lastly, we need to add a deployment file that instructs Netlify to build our application effectively. To do this, we need to create a `netlify.toml` file in the root directory of our project and add the snippet below:

```toml
[functions]
  node_bundler = "esbuild"
```

**Building the User Interface**
With that done, we can call the Serverless Function from our application UI. To do this, first, we need to update the `index.js` file inside the `pages` folder as shown below:

```js
import Head from 'next/head';
import { useState } from 'react';

export default function Home() {
  const [value, setValue] = useState({
    name: '',
    email: '',
  });
  const [isLoading, setIsloading] = useState(false);

  const handleChange = (e) => {
    setValue({ ...value, [e.target.name]: e.target.value });
  };

  const handleSubmit = (e) => {
    setIsloading(true);
    e.preventDefault();
    const body = {
      name: value.name,
      email: value.email,
    };
    fetch('./.netlify/functions/saveandconfirm', {
      method: 'POST',
      body: JSON.stringify(body),
    }).then((_) => {
      alert('Confirmed successfully!');
      setValue({ ...value, name: '', email: '' });
      setIsloading(false);
    });
  };

  return (
    <div>
      <Head>
        <title>Event confirmation</title>
        <meta
          name='description'
          content='Generated by create next app'
        />
        <link rel='icon' href='/favicon.ico' />
      </Head>
      <main className='py-4 px-4 lg:py-10 lg:px-10 w-full'>
        <section className='flex justify-center'>
          <div className='px-4 py-2 border rounded-lg w-full lg:w-2/4'>
            <div className='border-b h-8 mb-4'>
              <h3 className='text-gray-700'>
                Confirm Attendance
              </h3>
            </div>
            <form onSubmit={handleSubmit}>
              <fieldset>
                <label className='text-sm text-gray-400 mb-4 block'>
                  Name
                </label>
                <input
                  name='name'
                  className='border w-full rounded-sm mb-6 p-2'
                  required
                  value={value.name}
                  onChange={handleChange}
                />
              </fieldset>
              <fieldset>
                <label className='text-sm text-gray-400 mb-4 block'>
                  Email
                </label>
                <input
                  name='email'
                  className='border w-full rounded-sm mb-6 p-2'
                  type='email'
                  required
                  value={value.email}
                  onChange={handleChange}
                />
              </fieldset>
              <button
                className='text-sm text-white px-8 py-2 rounded-sm bg-teal-600 hover:bg-teal-700'
                disabled={isLoading}
              >
                Submit
              </button>
            </form>
          </div>
        </section>
      </main>
    </div>
  );
}
```

The snippet above does the following:

- Imports the required dependencies
- **Line****s** **5-9**: Create state properties to manage application state
- **Line****s** **11-13**: Creates `handleChange` to control the input fields
- **Line****s** **15-30**: Makes a `POST` request to the Serverless Function we created earlier and pass in the required parameter
- Updates the UI accordingly 


## Putting it all together on Netlify

**Pushing our source code to GitHub**
We need to push our source code to GitHub to enable a seamless deployment process. To get started, we need to log into our GitHub account, create a repository, input `event-confirmation` as the name and **Create repository**.

Next, we initialize a `git` project and save recent changes in our project by running the command below:

```bash
git init
git add .
git commit -m "event confirmation source code"
```

To push our changes, copy and run the highlighted commands on the terminal:

![Push changes to GitHub](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667650453977_Screenshot+2022-11-05+at+13.13.38.png)


**Deploying to Netlify**
To get started, we need to log into our [Netlify](https://app.netlify.com/) dashboard. Click on **Add new site** dropdown and select  **Import an existing project**.

![Create site](https://paper-attachments.dropboxusercontent.com/s_A1144B74EC1072093F0D2701A540D1E74AD827D7B0FFCD60C26EE8B5BA462734_1667252724024_Screenshot+2022-10-29+at+19.48.13.png)


Select **GitHub** as the Git provider and authorize Netlify. 

![select Github](https://paper-attachments.dropboxusercontent.com/s_8D31A8FC979E5F8A04C65B533C8604145C4DC40C7A1F1BAA5C7B6711437D62F0_1647646116402_Screenshot+2022-03-19+at+00.27.32.png)


Search for `event-confirmation` and select the repository.

![select repository](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667650878264_Screenshot+2022-11-05+at+13.21.03.png)


Click on **Show advanced**, click the **New variable** button and add the `XATA_URL`, `XATA_API_KEY`, `SEND_FROM_EMAIL`, and `NETLIFY_EMAIL_SECRET` environment variables as key and their corresponding values.

![Show advanced](https://paper-attachments.dropboxusercontent.com/s_A1144B74EC1072093F0D2701A540D1E74AD827D7B0FFCD60C26EE8B5BA462734_1667253099549_Screenshot+2022-10-29+at+19.50.21.png)
![input env variable](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667650899396_Screenshot+2022-11-04+at+21.57.48.png)


As earlier mentioned we can get the needed values from Xata workspace and SendGrid dashboard.


![URL](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667651146272_Screenshot+2022-11-05+at+13.25.05.png)
![API KEY](https://paper-attachments.dropboxusercontent.com/s_A1144B74EC1072093F0D2701A540D1E74AD827D7B0FFCD60C26EE8B5BA462734_1667253588385_Screenshot+2022-10-29+at+16.46.22.png)



Click the **Deploy site** button to start deployment. It might take a few minutes.

**Configure email integration**
To do this, click the **Site settings** button to view the deployed site settings.

![site setting](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667658527728_Screenshot+2022-11-04+at+22.01.19.png)


Navigate to the **Emails** tab and click the **Enable emails** button.


![Email tab](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667658598838_Screenshot+2022-11-04+at+22.02.23.png)
![Enable emails](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667658598877_Screenshot+2022-11-04+at+22.03.05.png)


Select `SendGrid` as the email provider, input the API key we generated earlier on SendGrid, and **Save**.

![Input SendGrid details](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667658752119_Screenshot+2022-11-04+at+22.03.52.png)


Finally, to sync the latest changes with our deployed application, we need to navigate to the **Deploys** tab and trigger redeployment by clicking the **Clear cache and deploy site** option.

![Trigger deployment](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667659264446_Screenshot+2022-11-05+at+15.38.06.png)


With that done, we can test our application by clicking on the deployed URL

![Test application](https://paper-attachments.dropboxusercontent.com/s_F9ED1B6D8C4DDD34CCA6289B797D0511BC2E249FDC71E6703551C91F0D4351A9_1667659444749_Screenshot+2022-11-05+at+15.40.13.png)

![](https://media.giphy.com/media/ORKNdc9G18aDPzrjBw/giphy.gif)


[https://media.giphy.com/media/ORKNdc9G18aDPzrjBw/giphy.gif](https://media.giphy.com/media/ORKNdc9G18aDPzrjBw/giphy.gif)


## Conclusion

This post discussed how to save event details and trigger an email in a Netx.js application using Xata, SendGrid, and Netlify. With this approach, developers can streamline their architectural process by leveraging out-of-the-box solutions to cater to storing users' data and sending dynamic emails.

These resources might be helpful:

- [Xata official docs](https://xata.io/docs/overview?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog)
- [Cloudinary official docs](https://cloudinary.com/documentation?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog)
- [Netlify email integration](https://docs.netlify.com/netlify-labs/experimental-features/email-integration/?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog)
- [TailwindCSS](https://tailwindcss.com/)