Overview

aSaaSin renders transactional emails with React Email and sends them through Resend. We mirror app colors via a custom <Tailwind /> wrapper and load a web font so emails match site styling.

Elements & layout

Build emails from small blocks; here are the pieces we use and why:

  • Html, Head, Body: email document shell; always include these for consistent rendering.
  • Preview: short preview line shown by clients next to the subject.
  • Container: fixed-width content area; center and add padding.
  • Section: stackable layout rows; use for spacing and grouping.
  • Heading, Text, Link, Img, Hr, Button: basic content primitives with email-safe attributes.
  • <Tailwind />: wraps children and provides a minimal Tailwind config (colors only) so you can use the same tokens as the app.
  • <Font />: declares a web font once; clients that support remote fonts will use it, others fall back.

Share Tailwind tokens

Extend React Email’s Tailwind config with the app’s HexColors so classes like bg-secondary-dark and text-primary-light work the same as in the UI.

// emails/tailwind.tsx — reuse app colors inside emails
import { Tailwind as ReactEmailTailwind, TailwindProps } from '@react-email/components';
import * as React from 'react';
import { HexColors } from '@/constants/colors';

const Tailwind: React.FC<TailwindProps> = (props) => (
  <ReactEmailTailwind
    {...props}
    config={{
      theme: {
        extend: {
          colors: { ...HexColors },
        },
      },
    }}
  />
);

export default Tailwind;

Font setup

Declare a web font once and reuse it across templates; React Email injects the correct @font-face rules.

// emails/font.tsx — declare a web font for supported clients
import { Font as ReactEmailFont } from '@react-email/components';
import * as React from 'react';

const Font: React.FC = () => (
  <ReactEmailFont
    fontFamily="Bricolage Grotesque"
    fallbackFontFamily="sans-serif"
    webFont={{
      url: 'https://fonts.gstatic.com/s/bricolagegrotesque/v7/3y9K6as8bTXq_nANBjzKo3IeZx8z6up5BeSl9D4dj_x9PpZBMlGIInHWVyNJ.woff2',
      format: 'woff2',
    }}
    fontWeight="400 700"
  />
);

export default Font;

Many clients (Apple Mail/iOS) support remote fonts; Gmail web often does not. Always include a solid fallback stack.

Config Google Font

Get the .woff2 URL from Google Fonts so you can supply it to <Font />:

  1. Open the font on Google Fonts (e.g., Bricolage Grotesque) and click Get font / Select styles.
  2. Under Use on the web, choose link, select weights you need (e.g., 400, 700), and open the generated fonts.googleapis.com/css2 URL in a new tab.
  3. In the returned CSS, copy the https://fonts.gstatic.com/... .woff2 URL for the latin subset (smallest) and paste it into webFont.url.
  4. If you add italics or more weights later, regenerate the CSS and update the URL.

Simple example

Here’s a minimal template using our layout pieces and shared tokens.

// emails/Example.tsx — minimal skeleton
import { Html, Head, Preview, Body, Container, Section, Heading, Text } from '@react-email/components';
import Tailwind from '@/emails/tailwind';
import Font from '@/emails/font';

export default function ExampleEmail() {
  return (
    <Html>
      <Head><Font /></Head>
      <Preview>Short preview text</Preview>
      <Tailwind>
        <Body className="m-auto bg-secondary-dark px-2 font-sans">
          <Container className="mx-auto my-[40px] max-w-[465px] rounded-xl border border-neutral p-[20px]">
            <Section className="text-center">
              <Heading className="mb-3 text-[22px] font-bold text-primary-light">Hello!</Heading>
              <Text className="text-[14px] leading-[24px] text-primary-light">
                This is a minimal React Email template styled with aSaaSin tokens.
              </Text>
            </Section>
          </Container>
        </Body>
      </Tailwind>
    </Html>
  );
}

Send with Resend

We send from the server using Resend—simple API, React component payloads, and reliable infrastructure.

import { Resend } from 'resend';
import ExampleEmail from '@/emails/Example';

const resend = new Resend(process.env.RESEND_API_KEY!);

export async function sendExampleEmail(to: string) {
  const { data, error } = await resend.emails.send({
    from: 'aSaaSin <noreply@your-domain.tld>',
    to,
    subject: 'Hello from aSaaSin',
    react: <ExampleEmail />,
  });
  return error
    ? { success: false, error: error.message }
    : { success: true, id: data?.id };
}

Tips

  • Keep templates small and linear; prefer simple layout stacks (Section, Container).
  • Snapshot-test rendered HTML to catch regressions.
  • Reuse app tokens (HexColors) so emails and site stay visually consistent.