react-email

Par resend · resend-skills

À utiliser lors de la création de templates d'e-mails HTML avec des composants React, de l'ajout d'un éditeur visuel d'e-mails à une application via l'éditeur visuel React Email, du rendu d'e-mails en HTML, ou de l'envoi d'e-mails avec Resend. Couvre les e-mails de bienvenue, les réinitialisations de mot de passe, les notifications, les confirmations de commande, les newsletters, les e-mails transactionnels, ainsi que le composant d'éditeur d'e-mails intégrable.

npx skills add https://github.com/resend/resend-skills --skill react-email

React Email

Construisez et envoyez des emails HTML en utilisant des composants React — une approche moderne et basée sur les composants pour le développement d'emails qui fonctionne sur tous les principaux clients de messagerie.

Installation

Créez un nouveau projet React Email, installez les dépendances et démarrez le serveur de développement :

npx create-email@latest
cd react-email-starter
npm install
npm run dev

Cela fonctionne avec n'importe quel gestionnaire de paquets (npm, yarn, pnpm, bun) — adaptez en conséquence.

Le serveur de développement s'exécute sur localhost:3000 avec une interface de prévisualisation pour les modèles dans le dossier emails.

Ajouter à un projet existant

Installez les paquets et ajoutez un script à votre package.json :

{
  "scripts": {
    "email": "email dev --dir emails --port 3000"
  }
}

Assurez-vous que le chemin vers le dossier emails est relatif au répertoire de base du projet. Vérifiez que tsconfig.json inclut un support approprié pour JSX.

Modèle d'email basique

Créez un composant email avec une structure appropriée en utilisant le composant Tailwind pour le style :

import {
  Html,
  Head,
  Preview,
  Body,
  Container,
  Heading,
  Text,
  Button,
  Tailwind,
  pixelBasedPreset
} from '@react-email/components';

interface WelcomeEmailProps {
  name: string;
  verificationUrl: string;
}

export default function WelcomeEmail({ name, verificationUrl }: WelcomeEmailProps) {
  return (
    <Html lang="en">
      <Tailwind
        config={{
          presets: [pixelBasedPreset],
          theme: {
            extend: {
              colors: {
                brand: '#007bff',
              },
            },
          },
        }}
      >
        <Head />
        <Body className="bg-gray-100 font-sans">
          <Preview>Welcome - Verify your email</Preview>
          <Container className="max-w-xl mx-auto p-5">
            <Heading className="text-2xl text-gray-800">
              Welcome!
            </Heading>
            <Text className="text-base text-gray-800">
              Hi {name}, thanks for signing up!
            </Text>
            <Button
              href={verificationUrl}
              className="bg-brand text-white px-5 py-3 rounded block text-center no-underline box-border"
            >
              Verify Email
            </Button>
          </Container>
        </Body>
      </Tailwind>
    </Html>
  );
}

// Preview props for testing
WelcomeEmail.PreviewProps = {
  name: 'John Doe',
  verificationUrl: 'https://example.com/verify/abc123'
} satisfies WelcomeEmailProps;

export { WelcomeEmail };

Directives de comportement

  • Lors de l'itération sur le code, mettez à jour uniquement ce que l'utilisateur a demandé. Conservez le reste intact.
  • Si l'utilisateur demande d'utiliser des media queries, informez-le que la plupart des clients de messagerie ne les supportent pas et suggérez une approche différente.
  • N'utilisez jamais directement les variables de modèle (comme {{name}}) dans le code TypeScript. Référencez plutôt les propriétés sous-jacentes directement. Si l'utilisateur demande explicitement {{variableName}}, placez la chaîne mustache uniquement dans PreviewProps, jamais dans le JSX du composant :
const EmailTemplate = (props) => {
  return (
    <h1>Hello, {props.variableName}!</h1>
  );
}

EmailTemplate.PreviewProps = {
  variableName: "{{variableName}}",
};

export default EmailTemplate;
  • N'écrivez jamais le motif {{variableName}} directement dans la structure du composant. Si l'utilisateur insiste, expliquez que cela rendrait le modèle invalide.

Composants essentiels

Consultez references/COMPONENTS.md pour la documentation complète des composants.

Structure de base :

  • Html - Enveloppe racine avec attribut lang
  • Head - Éléments meta, styles, polices
  • Body - Enveloppe du contenu principal
  • Container - Enveloppe de centrage la plus externe (a un max-width: 37.5em intégré). À utiliser une seule fois par email.
  • Section - Blocs de contenu intérieur (pas de max-width intégré). À utiliser pour regrouper le contenu à l'intérieur de Container.
  • Row & Column - Mises en page multi-colonnes
  • Tailwind - Active les classes d'utilitaires Tailwind CSS

Contenu :

  • Preview - Texte de prévisualisation de la boîte de réception, toujours en premier dans <Body>
  • Heading - Titres h1-h6
  • Text - Paragraphes
  • Button - Boutons de lien stylisés (incluez toujours box-border)
  • Link - Hyperliens
  • Img - Images (consultez la section Fichiers statiques ci-dessous)
  • Hr - Séparateurs horizontaux

Spécialisés :

  • CodeBlock - Code avec coloration syntaxique
  • CodeInline - Code en ligne
  • Markdown - Rendu markdown
  • Font - Polices web personnalisées

Avant d'écrire du code

Quand un utilisateur demande un modèle d'email, posez d'abord des questions clarificatrices s'il n'a pas fourni :

  1. Couleurs de marque - Demandez la couleur de marque primaire (code hex comme #007bff)
  2. Logo - Demandez s'il a un fichier logo et son format (PNG/JPG uniquement - avertissez si SVG/WEBP)
  3. Préférence de style - Ton professionnel, décontracté ou minimaliste
  4. URL de production - Où les assets statiques seront-ils hébergés en production ?

Fichiers statiques et images

Structure de répertoire

Les images locales doivent être placées dans le dossier static à l'intérieur de votre répertoire emails :

project/
├── emails/
│   ├── welcome.tsx
│   └── static/           <-- Les images vont ici
│       └── logo.png

URLs de développement vs production

Utilisez ce motif pour les images qui fonctionnent à la fois en prévisualisation de développement et en production :

const baseURL = process.env.NODE_ENV === "production"
  ? "https://cdn.example.com"  // CDN de production de l'utilisateur
  : "";

export default function Email() {
  return (
    <Img
      src={`${baseURL}/static/logo.png`}
      alt="Logo"
      width="150"
      height="50"
    />
  );
}

Comment ça fonctionne :

  • Développement : baseURL est vide, donc l'URL est /static/logo.png - servie par le serveur de développement React Email
  • Production : baseURL est le domaine CDN, donc l'URL est https://cdn.example.com/static/logo.png

Important : Demandez toujours à l'utilisateur son URL d'hébergement en production. Ne codez pas en dur localhost:3000.

Style

Consultez references/STYLING.md pour la documentation complète du style, incluant la typographie, les motifs de mise en page, le mode sombre et la cohérence de marque.

Règles clés

  • Utilisez Tailwind avec pixelBasedPreset (les clients de messagerie ne supportent pas rem). Importez pixelBasedPreset depuis @react-email/components.
  • N'utilisez jamais flexbox ou grid — utilisez les composants Row/Column ou les tableaux pour les mises en page.
  • Évitez les media queries CSS/Tailwind (sm:, md:, lg:, xl:) — support limité des clients de messagerie.
  • N'utilisez jamais les sélecteurs de thème (dark:, light:) — non supportés.
  • N'utilisez jamais les images SVG ou WEBP — avertissez les utilisateurs des problèmes de rendu.
  • Spécifiez toujours le type de bordure (border-solid, border-dashed, etc.) — les clients de messagerie ne l'héritent pas.
  • Pour les bordures d'un seul côté, réinitialisez d'abord les autres (border-none border-l border-solid).

Classes requises

Composant Classe requise Pourquoi
Button box-border Empêche le padding de dépasser la largeur du bouton
Hr / n'importe quelle bordure border-solid (ou border-dashed, etc.) Les clients de messagerie n'héritent pas du type de bordure
Bordures d'un seul côté border-none + le côté Réinitialise les bordures par défaut sur les autres côtés

Notes de structure

  • Définissez toujours <Head /> à l'intérieur de <Tailwind> quand vous utilisez Tailwind CSS
  • <Preview> doit toujours être le premier élément à l'intérieur de <Body>
  • Incluez uniquement les props dans PreviewProps que le composant utilise réellement
  • Utilisez une largeur/hauteur fixe pour les éléments de taille connue (logos, icônes) ; dimensionnement réactif (w-full, h-auto) pour les images de contenu

Rendu

Convertir en HTML

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

const html = await render(
  <WelcomeEmail name="John" verificationUrl="https://example.com/verify" />
);

Convertir en texte brut

const text = await render(<WelcomeEmail name="John" verificationUrl="https://example.com/verify" />, { plainText: true });

Envoi

React Email supporte l'envoi avec n'importe quel fournisseur de service de messagerie. Consultez references/SENDING.md pour la documentation complète d'envoi incluant des exemples avec Resend, Nodemailer et SendGrid.

Exemple rapide en utilisant le SDK Resend :

import { Resend } from 'resend';
import { WelcomeEmail } from './emails/welcome';

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

const { data, error } = await resend.emails.send({
  from: 'Acme <onboarding@resend.dev>',
  to: ['user@example.com'],
  subject: 'Welcome to Acme',
  react: <WelcomeEmail name="John" verificationUrl="https://example.com/verify" />
});

Le SDK Node de Resend gère automatiquement le rendu HTML et en texte brut.

Commandes CLI

Le paquet react-email fournit une CLI accessible via la commande email :

Commande Description
email dev --dir <path> --port <port> Démarrez le serveur de développement de prévisualisation (par défaut : ./emails, port 3000)
email build --dir <path> Construisez l'app de prévisualisation pour le déploiement en production
email start Exécutez l'app de prévisualisation construite
email export --outDir <path> --pretty --plainText --dir <path> Exportez les modèles en fichiers HTML statiques
email resend setup Connectez la CLI à votre compte Resend via clé API
email resend reset Supprimez la clé API Resend stockée

Internationalisation

Consultez references/I18N.md pour la documentation complète de i18n. React Email supporte trois bibliothèques : next-intl, react-i18next et react-intl.

Éditeur d'email

React Email inclut un éditeur visuel (@react-email/editor) qui peut être intégré dans votre app. Il est construit sur TipTap/ProseMirror et produit du HTML prêt pour les emails.

Consultez references/EDITOR.md pour la documentation complète incluant :

  • EmailEditor — composant prêt à l'emploi avec menus bulles, commandes slash et thème
  • StarterKit — 35+ extensions sensibles aux emails (titres, listes, tableaux, colonnes, boutons, etc.)
  • Inspector — barre latérale contextuelle pour éditer les styles
  • EmailTheming — thèmes intégrés (basic, minimal) avec propriétés CSS personnalisables
  • composeReactEmail — exportez le contenu de l'éditeur en HTML et texte brut prêts pour les emails
  • Extensions personnalisées via EmailNode et EmailMark

Exemple rapide :

import { EmailEditor, type EmailEditorRef } from '@react-email/editor';
import '@react-email/editor/themes/default.css';
import { useRef } from 'react';

export function MyEditor() {
  const ref = useRef<EmailEditorRef>(null);

  return (
    <EmailEditor
      ref={ref}
      content="<p>Start typing...</p>"
      theme="basic"
    />
  );
}

Motifs courants

Consultez references/PATTERNS.md pour des exemples complets incluant :

  • Emails de réinitialisation de mot de passe
  • Confirmations de commande avec listes de produits
  • Emails de notification avec blocs de code
  • Mises en page multi-colonnes
  • Emails d'invitation d'équipe

Bonnes pratiques pour les emails

  1. Testez sur plusieurs clients de messagerie - Gmail, Outlook, Apple Mail, Yahoo Mail
  2. Gardez-le réactif - Largeur maximale autour de 600px, testez sur mobile
  3. Utilisez des URLs d'image absolues - Hébergez sur un CDN fiable, incluez toujours le texte alt
  4. Fournissez une version en texte brut - Requis pour l'accessibilité
  5. Gardez la taille du fichier sous 102 KB - Gmail tronque les emails plus grands
  6. Ajoutez les types TypeScript appropriés - Définissez des interfaces pour tous les props de l'email
  7. Incluez les props de prévisualisation - Ajoutez .PreviewProps pour les tests de développement
  8. Utilisez des domaines vérifiés - Pour les adresses from en production

Ressources supplémentaires

Skills similaires