React Email First Look 🎉
Tags: react, typescript, email, javascript
Published: 2023-01-30 06:25:12

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
```
- 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
```
- Install dependencies by running:

```
npm install
```
- Alright, now spin it up for server by:

```
npm run dev
```

- If everything is done right you will see the following screen on **"http://localhost:3000/"**

![React Email Screen](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xi11k0e966pafrnjw0rj.png)

**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](https://react.email/docs/introduction).

- I am going with the vercel one:
![Template](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n3b2y1iw07en6jgg1ird.png)

- Paste following code:

```jsx
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',
};

```

- Output will look like: 

![My Custom Email](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4t35txqkxlz8r9gt2c8z.png)

- 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](https://react.email/docs/integrations/overview).

- First, install the following dependencies: 
```
npm install @react-email/render nodemailer
```

- Now, Create a new file and paste the following code:
```jsx
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);
```
- 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.