Sending emails in JavaScript: Next.js+Brevo

12/06/2024

Sending emails in JavaScript

In this article, you’ll learn how to add a contact form to your Next.js SSR application (with TypeScript). We will use the Brevo API to send emails in JavaScript. Brevo is one of the most popular Email Service Providers (ESPs), to send emails.

Why Should You Use Brevo for sending emails in JavaScript?

Using Brevo's API, you can send transactional emails or you can automate your email marketing directly within your app, bypassing the need for a separate interface. Email marketing remains one of the most cost-effective channels for customer engagement.

If you haven’t signed up for Brevo yet, you can create an account here and start exploring its API.

Brevo (formerly known as Sendinblue) is a robust, all-in-one marketing platform, offering tools for email and SMS campaigns, marketing automation, and much more. Its API is well-documented and flexible, allowing you to fully control email sending from your application while integrating seamlessly with your tech stack.

To follow along, make sure you have:

  • A Brevo account Create free account Compare plans

  • A Next.js application set up and running

  • Access to your Brevo API key, which you can find in your Brevo account under SMTP & API

Step-by-Step Guide to Sending an Email with Brevo API in Next.js

Step 1: Install Axios

We’ll use Axios to send HTTP requests to Brevo’s API from Next.js. If you haven’t installed Axios yet, you can do so by running:

npm install axios

Configure Brevo API Key

Create your API key in Brevo's Dashboard Settings > Keys > API

Brevo Create API Key

In the root of your Next.js project, create a .env file (or addd to existing one) to securely store your Brevo API key:

BREVO_API_KEY=your_brevo_api_key_here

Set Up the Email-Sending Function

Create a function to handle sending emails using Brevo's API. Inside your Next.js project, create a new file in the /pages/api directory, such as /pages/api/contact.js

import axios from "axios";

export default async function handler(req, res) {
  if (req.method === "POST") {
    const { name, email, message } = req.body;
    try {
      const response = await axios.post(
        "https://api.brevo.com/v3/smtp/email",
        {
          sender: {
            name: process.env.TARGET_NAME,
            email: process.env.TARGET_EMAIL,
          },
          to: [{ email: process.env.TARGET_EMAIL }],
          subject: "Contact Form Submission",
          htmlContent: `<html>
              <body>
                <h1>Contact Form Submission</h1>
                <p><strong>Name:</strong> ${name}</p>
                <p><strong>Email:</strong> ${email}</p>
                <p><strong>Message:</strong></p>
                <p>${message}</p>
              </body>
            </html>
          `,
        },
        {
          headers: {
            "api-key": process.env.BREVO_API_KEY,
            "Content-Type": "application/json",
            accept: "application/json",
          },
        }
      );

      return res
        .status(200)
        .json({ message: "Email sent successfully!", data: response.data });
    } catch (error) {
      console.error("Error sending email:", error);
      return res
        .status(500)
        .json({ error: "Failed to send email", details: error.message });
    }
  } else {
    res.setHeader("Allow", ["POST"]);
    return res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}

Create a Form

You can create a form in a component (e.g., components/EmailForm.js) that will submit data to this API endpoint.

"use client";
import { useState } from "react";

export default function EmailForm() {
  const [email, setEmail] = useState("");
  const [name, setName] = useState("");
  const [message, setMessage] = useState("");

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const response = await fetch("/api/contact", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email, name, message }),
      });

      if (response.ok) {
        alert("Email sent successfully!");
      } else {
        alert("Failed to send email.");
      }
    } catch (error) {
      console.error("Error:", error);
      alert("An error occurred.");
    }
  };

  return (
    <form
      onSubmit={handleSubmit}
      className="max-w-md mx-auto p-6 bg-white rounded-lg shadow-md"
    >
      <input
        type="text"
        placeholder="Name"
        value={name}
        onChange={(e)=> setName(e.target.value)}
        required
        className="w-full px-4 py-2 mb-4 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
      />
      <input
        type="email"
        placeholder="Email"
        value={email}
        onChange={(e)=> setEmail(e.target.value)}
        required
        className="w-full px-4 py-2 mb-4 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
      />
      <textarea
        placeholder="Your Message"
        value={message}
        onChange={(e)=> setMessage(e.target.value)}
        required
        className="w-full px-4 py-2 mb-4 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none"
        rows={4}
      ></textarea>
      <button
        type="submit"
        className="w-full px-4 py-2 text-white bg-blue-600 rounded-md hover:bg-blue-700 transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"
      >
        Send
      </button>
    </form>
  );
}

Troubleshooting Email Sending Issues

If you're getting 403 error, it might be this one:

{"message":"Unable to send email. Your SMTP account is not yet activated. Please contact us at contact@sendinblue.com to request activation","code":"permission_denied"}

Your account hasn't been activated yet. You may encounter similar issue when trying to send from the user interface:

Brevo account not yet activated

You need to complete your account creation and receive a confirmation email stating, 'Your account has been validated.'

Sign Up to get a ZIP with complete working demo app

Tech stack: Next.js 15 (SSR mode), TypeScript, Axios, Tailwind.

Contact form next.js typescript

Sending emails in JavaScript often takes place on public websites, which makes such contact forms vulnerable to spam bots. If they find a form on your site, they will attempt to fill it out and submit it.

Next, we will implement additional security checks. Currently, there is only one check in place: the form will not work without JavaScript enabled. However, this is definitely not enough to prevent spam. Subscribe to stay informed about updates.

Exclusive content
Bonus Tips
Early content access