DEV Community

Cover image for React Email First Look πŸŽ‰
Dipesh Jaiswal
Dipesh Jaiswal

Posted on

React Email First Look πŸŽ‰

At some point it feels like every developer ends up writing some kind of emailing system. It could be something as simple as a single email for somebody who fills out a form or a more complex flow for a SAS product. But whatever the use case, if you've ever tried to write an email from scratch in 2023, you know it's a pain in the butt. It's just not an enjoyable experience. Well, what if you could write emails with react and TypeScript?

Currently in beta, React Email allows you to write emails with the same syntax as React. This means you can easily create and edit email templates using JSX.

Lets get started πŸš€

1. Project Setup

First start with setting up the project in your system.

  • Paste the following code in your terminal:
npx create-email@latest
Enter fullscreen mode Exit fullscreen mode
  • This will create a new folder called react-email-starter with a few email templates.

  • Now, change your current directory by:

cd react-email-starter
Enter fullscreen mode Exit fullscreen mode
  • Install dependencies by running:
npm install
Enter fullscreen mode Exit fullscreen mode
  • Alright, now spin it up for server by:
npm run dev
Enter fullscreen mode Exit fullscreen mode

React Email Screen

2. Generating Email with React!

  • Lets start editing the pre build template by the awesome "React Email Team".
  • Although you can also explorer more templates or create your own custom one by following the documentation.

  • I am going with the vercel one:
    Template

  • Paste following code:

import { Button } from '@react-email/button';
import { Container } from '@react-email/container';
import { Head } from '@react-email/head';
import { Hr } from '@react-email/hr';
import { Html } from '@react-email/html';
import { Img } from '@react-email/img';
import { Link } from '@react-email/link';
import { Preview } from '@react-email/preview';
import { Section } from '@react-email/section';
import { Text } from '@react-email/text';
import * as React from 'react';

export default function Email() {
  return (
    <Html>
      <Head />
      <Preview>Join my team</Preview>
      <Section style={main}>
        <Container style={container}>
          <Section style={{ marginTop: '32px' }}>
            <Img
              src="https://dipeshjaiswal.com/static/logos/dipeshjaiswal_logo.png"
              width="40"
              height="37"
              alt="Vercel"
              style={logo}
            />
          </Section>
          <Text style={h1}>
            Join <strong>My Awesome</strong> Project <strong></strong>
          </Text>
          <Text style={text}>Hello zenorocha,</Text>
          <Text style={text}>
            <strong>John Doe</strong> (
            <Link href="mailto:youremail@domain.com" style={link}>
            youremail@domain.com
            </Link>
            ) has invited you to the <strong>My Project</strong> team.
          </Text>
          <table
            style={spacing}
            border={0}
            cellPadding="0"
            cellSpacing="10"
            align="center"
          >
            <tr>
              <td style={center} align="left" valign="middle">
                <Img
                  style={avatar}
                  src="/static/myemoji.png"
                  width="64"
                  height="64"
                />
              </td>
              <td style={center} align="left" valign="middle">
                <Img
                  src="/static/vercel-arrow.png"
                  width="12"
                  height="9"
                  alt="invited you to"
                />
              </td>
              <td style={center} align="left" valign="middle">
                <Img
                  style={avatar}
                  src="https://dipeshjaiswal.com/static/logos/dipeshjaiswal_logo.png"
                  width="64"
                  height="64"
                />
              </td>
            </tr>
          </table>
          <Section style={{ textAlign: 'center' }}>
            <Button
              pX={20}
              pY={12}
              style={btn}
              href="https://domain.com/teams/invite"
            >
              Join the team
            </Button>
          </Section>
          <Text style={text}>
            <br />
            or copy and paste this URL into your browser:{' '}
            <Link
              href="https://domain.com/teams/invite"
              target="_blank"
              style={link}
              rel="noreferrer"
            >
              https://domain.com/teams/invite
            </Link>
          </Text>
          <Hr style={hr} />
          <Text style={footer}>
            This invitation was intended for{' '}
            <span style={black}>zenorocha</span>.This invite was sent from{' '}
            <span style={black}>204.13.186.218</span> located in{' '}
            <span style={black}>SΓ£o Paulo, Brazil</span>. If you were not
            expecting this invitation, you can ignore this email. If you are
            concerned about your account's safety, please reply to this email to
            get in touch with us.
          </Text>
        </Container>
      </Section>
    </Html>
  );
}

const main = {
  backgroundColor: '#ffffff',
  margin: '0 auto',
};

const container = {
  border: '1px solid #eaeaea',
  borderRadius: '5px',
  margin: '40px auto',
  padding: '20px',
  width: '465px',
};

const logo = {
  margin: '0 auto',
};

const h1 = {
  color: '#000',
  fontFamily:
    "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif",
  fontSize: '24px',
  fontWeight: 'normal',
  textAlign: 'center' as const,
  margin: '30px 0',
  padding: '0',
};

const avatar = {
  borderRadius: '100%',
};

const link = {
  color: '#067df7',
  textDecoration: 'none',
};

const text = {
  color: '#000',
  fontFamily:
    "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif",
  fontSize: '14px',
  lineHeight: '24px',
};

const black = {
  color: 'black',
};

const center = {
  verticalAlign: 'middle',
};

const btn = {
  backgroundColor: 'rgb(0,199,255)',
  borderRadius: '5px',
  color: '#fff',
  fontFamily:
    "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif",
  fontSize: '12px',
  fontWeight: 500,
  lineHeight: '50px',
  textDecoration: 'none',
  textAlign: 'center' as const,
};

const spacing = {
  marginBottom: '26px',
};

const hr = {
  border: 'none',
  borderTop: '1px solid #eaeaea',
  margin: '26px 0',
  width: '100%',
};

const footer = {
  color: '#666666',
  fontFamily:
    "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif",
  fontSize: '12px',
  lineHeight: '24px',
};

Enter fullscreen mode Exit fullscreen mode
  • Output will look like:

My Custom Email

  • You can always play with your favourite colors & theme in your favourite framework ReactπŸ˜‰.

3. Let's Setup Mailing Integration

  • Once, you are happy with your email its time to start sending it to the user.
  • I will be using Nodemailer but you can check other as well in documentation.

  • First, install the following dependencies:

npm install @react-email/render nodemailer
Enter fullscreen mode Exit fullscreen mode
  • Now, Create a new file and paste the following code:
import * as React from 'react';
import { render } from '@react-email/render';
import nodemailer from 'nodemailer';
import MyCustomEmail from './vercel-invite-user';

const transporter = nodemailer.createTransport({
  host: 'smtp.ethereal.email',
  port: 587,
  secure: false,
  auth: {
    user: 'my_user',
    pass: 'my_password',
  },
});

const emailHtml = render(<MyCustomEmail />);

const options = {
  from: 'you@example.com',
  to: 'user@gmail.com',
  subject: 'My Awesome Project',
  html: emailHtml,
};

transporter.sendMail(options);
Enter fullscreen mode Exit fullscreen mode
  • The render() function returns your custom React Email template in HTML format, which can be understood by mailing servers like Gmail or Outlook.
  • You can then pass this HTML to your mailer, in this case, Nodemailer Transporter.
  • And thats all you need to create a beautiful Emails with React.

4. Preview your Email

  • If you come over this way, you can actually send yourself a preview of this.
  • Click on the "Send" button in the top right corner and type in your own email.
  • Click Send and you'll receive a preview of your email in your inbox, and that's all you need to create beautiful emails with React.

In conclusion, React Email allows developers to create beautiful and functional emails with the power of React and TypeScript. By using the pre-built templates or creating custom designs, developers can easily create emails that are both visually appealing and functional. With the added benefit of being able to preview and send emails directly from the application, React Email makes the process of building emails a much more enjoyable and efficient experience. Give React Email a try and see the difference it can make in your email development process.

Top comments (11)

Collapse
 
zenorocha profile image
Zeno Rocha

This is Zeno, one of the creators of React Email.

What a great article, thanks for taking the time to write it!

Collapse
 
dipeshjaiswal profile image
Dipesh Jaiswal

Thanks, Zeno! I'm thrilled that you enjoyed my article.

Collapse
 
ravavyr profile image
Ravavyr • Edited

This sounds like a nice idea, until it really really isn't.

  1. Do not create custom HTML emails using React. We literally have dozens of services [mailchimp, constant contact, icontact, mailersend, mailjet, and so on and so on] that have drag and drop email builders that are made to work across devices and email programs.
    Writing your own means you're asking to get complaints about layout issues, or worse getting tossed into the spam folder for bad structure or bad css or bad whatever.
    BTW: mailersend.com is free up to 12k emails/month.

  2. The second part is the even bigger problem. Nodemailer is just as bad as using PHP's native mail() function. You are choosing to send emails directly from your one server. This means your unknown IP is gonna send out emails and you probably don't have your DNS records setup for it. You need an SPF record, a DMARC record and more in some cases to verify the domain sendin emails is your domain and on top of that that example doesn't set headers for nodemailer so stuff like "reply to" or if it's text or html content aren't there either. This is instant-to-spam for many firewalls.

So, yes, this is fun if you're gonna write a tool that sends yourself a handful of automated emails and you whitelist it in your own email client, but this is very bad practice for any business website or site that wants to grow its traffic.

A late 3 i just thought of.
Some will go "but what about dynamic emails i need to send from code!"
Most of the services i listed above let you design templates with drag and drop tools and you can set variables in them that you pass to them via their API. So your code will process data, create some objects and send that data to them and they generate and send the emails. Just wanted to clarify that.

Collapse
 
bukinoshita profile image
Bu Kinoshita

Most of drag-n-drop email builders are buggy or limited. We want to make it easier for people to create, preview, and test emails with React Email, the same way you build websites.

We built our react email components following best practices to work on the majority of the emails clients, even the new ones like Supehuman or Hey. We test our components for compatibility and spam issues.

We also have been using React Email at Resend and sending thousands of emails weekly and monitor for bounced/spam emails.

That being said, a lot of people are using React Email in production and we didn't get any complains yet. There's a lot of things we still want to improve and explore ✌️

Collapse
 
ravavyr profile image
Ravavyr

You are not wrong. Most sitebuilders/email builders are buggy and limited.
I'll tell you that mailersend is a good one. I'm trying out a few others, and really more often than not it's not about the email design itself, you can do that in code, but it's about using their SMTP service to send the emails so your emails don't go into spam and don't get blocked by firewalls. The worst being aol, outlook, and yahoo mail.

Looks to me like Resend is trying to compete with these services and uses React Email for building emails. Nothing wrong with that. I'll have to check it out eventually.

As for complaints, well those come at some point to all services, so good luck :)

Collapse
 
stevereid profile image
Steve Reid

Wow! I was unaware of this. Thanks for the heads up.

Collapse
 
adamthedeveloper profile image
Adam

Thank you so much for sharing this!

Collapse
 
naucode profile image
Al - Naucode

Hey, that was a nice read, you got my follow, keep writing πŸ˜‰

Collapse
 
dipeshjaiswal profile image
Dipesh Jaiswal

Sure, Thankss πŸ™ŒπŸ»

Collapse
 
ashishxcode profile image
Ashish Patel

What a read man πŸ”₯

Collapse
 
dipeshjaiswal profile image
Dipesh Jaiswal

Thanks ManπŸ™ŒπŸ»