Resend and React Email Integration

Nextbase comes with Resend and React Email configured. This makes creating/modifying email templates and sending them to your customers very easy.

Resend.com

Resend serves as the backbone for handling email delivery in Nextbase. It streamlines the process of sending emails, managing templates, and handling various aspects of email communication. With Resend, you can focus on creating compelling content, knowing that the delivery mechanism is robust and reliable.

You can use a different email service provider if you want to.

How to use Resend in Next.js?

Resend is usually configured like this in Next.js.

  1. Install resend as a dependency and then import it into your application.
  2. Create an account in Resend and get your API key.
  3. Add your API key to your environment variables.

Then, you can use it like this.

import { Resend } from 'resend';
import { supabase } from './supabase'; // Example supabase configuration
 
const resend = new Resend({
  apiKey: process.env.RESEND_API_KEY,
  // Other Resend configurations...
  smtp: {
    host: supabase.smtpHost,
    port: supabase.smtpPort,
    secure: supabase.smtpSecure,
    auth: {
      user: supabase.smtpUser,
      pass: supabase.smtpPassword,
    },
  },
});
 
export { resend };

React-email: Declarative Email Templating

react-email is a React library that allows you to compose email templates using familiar React components. Instead of dealing with complex HTML templates, you can leverage the power of React to create modular and dynamic email content. This integration aligns with the React philosophy, making it intuitive for developers already familiar with React development. Nextbase provides a seamless integration of Resend and react-email so that you can harness the benefits of both tools effortlessly.

emails folder

Nextbase comes with the emails folder configured as the repository for your React Email components. You can write your emails here and also preview them with the email development server by running yarn email-dev.

React Email Development Server

In Nextbase, a React Email development server is set up to streamline the process of writing and previewing emails. This development server allows developers to interactively design and visualize emails in a browser, facilitating a more efficient email template creation workflow.

Package.json Script

The React Email development server is typically configured as a script in the package.json file. The script is named "email:dev":

./package.json
{
  "scripts": {
    // Other scripts...
    "email:dev": "email dev"
  }
}

To start the React Email development server, developers can run the following command in the terminal:

yarn email-dev

This starts the React Email development server and provides a convenient way to preview email templates.

/src/emails:

src
|-- emails
| |-- welcome.tsx
| |-- SignInEmail.tsx
| |-- TeamInvitation.tsx
| |-- ...

Each file in the emails folder corresponds to a specific type of email, and it contains a React component responsible for rendering the content of that email. We can then send the emails using Resend. Here are some emails we already have in the emails folder:

WelcomeEmail.tsx:

import {
  Html,
  Head,
  Heading,
  Body,
  Button,
  Text,
  Container,
  Tailwind,
  Hr,
  Link,
} from "@react-email/components";
import React from "react";
 
interface welcomeEmailProps{
  appName:string;
  userName:string;
  purposeOfApp:string;
  makerName:string;
  positionInTeam:string;
  linkToApp:string;
  supportEmail:string;
  socialMediaLinks:string;
}
 
const WelcomeEmail = ({
  appName,
  userName,
  purposeOfApp,
  makerName,
  positionInTeam,
  linkToApp,
  supportEmail,
  socialMediaLinks,
}:welcomeEmailProps) => {
  return (
    <Html>
      <Head />
      <Tailwind>
        <Body className="bg-gray-100 font-sans font-light">
          <Container className="bg-white py-5 px-12 mx-auto">
            <Heading>Welcome to {appName} acme</Heading>
            <Hr className="my-5" />
            <Text className="text-base">Dear John {userName},</Text>
            <Text className="text-base">Greetings!</Text>
            <Text className="text-base">
              We're thrilled to welcome you to {appName} acme. Your account has
              been successfully created and is ready to use.
            </Text>
            <Text className="text-base">
              Through {appName} acme, our goal is to help you Lorem ipsum dolor
              sit amet consectetur adipisicing elit. {purposeOfApp}.
            </Text>
            <Text className="text-base">Click the button to get stated</Text>
 
            <Button
              href={linkToApp}
              className=" w-11/12 font-semibold text-center bg-black text-white p-2.5 rounded-lg"
            >
              Get Started
            </Button>
            <Hr className="my-5" />
            <Text className="text-base">
              Should you need any assistance or further information, feel free
              to reach out to our support team at{" "}
              <Link href={supportEmail}>support@acme.co.in</Link> or visit our
              FAQ section.
            </Text>
            <Text className="text-base">
              Stay connected with us on our social media platforms for the
              latest updates: {socialMediaLinks}{" "}
              <Link href={socialMediaLinks}>Twitter</Link>,{" "}
              <Link href={socialMediaLinks}>FaceBook</Link>.
            </Text>
 
            <Text className="text-base">
              Thank you for choosing acme. We're excited to have you on board!
            </Text>
            <Text className="text-base">Best Regards,</Text>
            <Text className="mb-0 text-base">Dany{makerName}</Text>
            <Text className="my-0 text-base">CEO {positionInTeam}</Text>
            <Text className="my-0 text-base">Acme {appName}</Text>
          </Container>
        </Body>
      </Tailwind>
    </Html>
  );
};
 
export default WelcomeEmail;
 

In this example, the WelcomeEmail component represents the content of a welcome email. This declarative approach simplifies the process of creating and maintaining various email templates in your application.

InvitationToJoin.tsx

This is the organization invitation email template. When a user is invited to join an organization, this email is sent to them.

// src/emails/InvitationToJoin.tsx
 
import React from "react";
import {
  Html,
  Head,
  Heading,
  Text,
  Tailwind,
  Hr,
  Container,
  Body,
  Button,
} from "@react-email/components";
 
interface InvitationToJoinProps {
  nameOfOrganisation: string;
  recipientName: string;
  senderName: string;
}
 
const InvitationToJoin: React.FC<InvitationToJoinProps> = ({
  nameOfOrganisation,
  recipientName,
  senderName,
}) => {
  return (
    <Html>
      <Head />
      <Tailwind>
        <Body className="bg-gray-200">
          <Container className="shadow-sm rounded-lg bg-white px-12 py-5 font-light font-sans">
            <Heading>
              {" "}
              Invitation to join organisation {nameOfOrganisation}
            </Heading>
            <Hr className="my-5" />
 
            <Text className="text-base">Dear {recipientName} James,</Text>
            <Text className="text-base">
              {senderName} has invited you to join {nameOfOrganisation} Organisation
            </Text>
 
            <Hr className="my-5" />
            <Text className="text-base">
              Click the button below to accept the invitation
            </Text>
            <Button
              href="#"
              className="text-base bg-black font-semibold text-white px-10 py-3 rounded"
            >
              Accept Invitation
            </Button>
 
            <Text className="text-base">Best regards,</Text>
            <Text className="text-base">
              Richard
              <br />
              CEO
              <br />
              Organisation
            </Text>
          </Container>
        </Body>
      </Tailwind>
    </Html>
  );
};
 
export default InvitationToJoin;
 

The email is then sent like this.

// Example code for triggering email sending
import { resend } from '../utils/email';
import InvitationToJoin from '../emails/InvitationToJoin';
 
// Other logic...
 
// Send organization invitation email
resend.emails.send({
  to: 'recipient@example.com',
  from: 'sender@example.com',
  subject: 'Invitation to Join',
  html: (
    <InvitationToJoin
      nameOfOrganisation="Example Org"
      recipientName="John"
      senderName="Danial"
    />
  ),
});

(Optional) Configure Resend with Supabase SMTP Server

It is recommended to use a third-party SMTP service for production environments in Supabase.

  • Reliability: Supabase built-in SMTP server is severely rate limited. It is only suitable for development and testing purposes. Supabase recommends using a third-party SMTP service for production environments. Resend provides a robust and reliable email delivery mechanism.

  • Observability: Resend provides a dashboard to monitor email delivery and other metrics.

In a production environment, it's crucial to ensure reliable email delivery. Ensure that Resend or another third-party SMTP service is configured in your Supabase project.

React Email and Resend Integration in Nextbase

See src/utils/api-routes/utils.ts for an example of how to we use Resend in Nextbase. Here the sendEmail function is used to send emails using Resend. It receives the email options as an argument and sends the email using Resend.

// src/utils/api-routes/utils.ts
 
// Import necessary dependencies
import { Resend } from 'resend';
import { errors } from '../errors';
 
// Define the type for email options
type EmailOptions = {
  to: string;
  from: string;
  subject: string;
  html: string;
};
 
// Function to send an email using Resend
export async function sendEmail(options: EmailOptions) {
  try {
    // Initialize Resend with the provided API key
    const resend = new Resend(process.env.RESEND_API_KEY);
 
    // Send the email using Resend
    return resend.emails.send(options);
  } catch (error) {
    // Handle errors and add them to the error tracking system
    errors.add(error);
  }
}

Configuration

You only require the API key to configure Resend. You can find the API key in the Resend dashboard.