Envello
Guide

Send React Email templates through Envello

React Email's render() produces a plain HTML string. Envello's POST /emails takes an html field. That's the entire integration - no plugin, no adapter.

1. Install React Email

React Email ships components and a renderer as separate packages. You only need the renderer at send time; the component package is for building the template itself.

npm install @react-email/components @react-email/render
2. Build the template

A React Email template is a regular React component. Write it once, preview it with React Email's own dev server, and reuse it anywhere you can call render().

// emails/welcome-email.tsx
import {
  Body,
  Container,
  Head,
  Heading,
  Html,
  Text,
} from "@react-email/components";

export function WelcomeEmail({ name }: { name: string }) {
  return (
    <Html>
      <Head />
      <Body style={{ fontFamily: "sans-serif", backgroundColor: "#f4f4f5" }}>
        <Container style={{ padding: "24px", backgroundColor: "#ffffff" }}>
          <Heading as="h2">Welcome, {name}!</Heading>
          <Text>
            Thanks for signing up. Your account is ready, and your first
            API key is waiting in the dashboard.
          </Text>
        </Container>
      </Body>
    </Html>
  );
}
3. Render it and send

Call render() right before you send, and pass the result straight into the html field of POST /emails. Using plain fetch:

import { render } from "@react-email/render";
import { WelcomeEmail } from "./emails/welcome-email";

// render() returns a plain HTML string - that's the whole integration.
// Envello's POST /emails takes that string directly in the `html` field,
// no adapter or plugin needed.
const html = await render(<WelcomeEmail name="Svenja" />);

const response = await fetch("https://api.envello.dev/v1/emails", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ENVELLO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    from: "Acme <[email protected]>",
    to: "[email protected]",
    subject: "Welcome to Acme",
    html,
  }),
});

const result = await response.json();
// { id: "b1e2...", status: "queued" }

Or with the Node SDK, which wraps the same request shape:

import { Envello } from "envello";
import { render } from "@react-email/render";
import { WelcomeEmail } from "./emails/welcome-email";

const envello = new Envello(process.env.ENVELLO_API_KEY!);

await envello.emails.send({
  from: "Acme <[email protected]>",
  to: "[email protected]",
  subject: "Welcome to Acme",
  html: await render(<WelcomeEmail name="Svenja" />),
});
4. Add a plain-text fallback (recommended)

POST /emails requires at least one of html or text. React Email's renderer can produce both from the same component, so there's rarely a reason to skip the text version.

import { render } from "@react-email/render";
import { WelcomeEmail } from "./emails/welcome-email";

const element = <WelcomeEmail name="Svenja" />;

await envello.emails.send({
  from: "Acme <[email protected]>",
  to: "[email protected]",
  subject: "Welcome to Acme",
  html: await render(element),
  // React Email's plain-text renderer - cheap to add, and it's what most
  // spam filters and screen readers fall back to if HTML rendering fails.
  text: await render(element, { plainText: true }),
});

A note on attachments and headers

React Email only produces the message body. Everything else on the request, to, cc/bcc, reply_to, headers, attachments, and send_at for scheduled sends, is set the same way whether the body came from React Email, a template string, or a templating engine. See the docs home for the full request reference.

Ready to send?

Get an API key and send your first React Email template today.