Back to results

Filtered result set

33 / 2280 matches

SkillHub ClubWrite Technical DocsFrontendFull StackTech Writer

react-email

React Email provides React components for building HTML emails that work across email clients. It offers core structure components, content elements, and specialized features like Tailwind support. The skill includes examples for welcome emails, newsletters, and team invitations with proper TypeScript typing and inline styling.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
18,213
Hot score
99
Updated
March 20, 2026
Overall rating
A8.3
Composite score
7.5
Best-practice grade
B75.6

Install command

npx @skill-hub/cli install resend-react-email-skills
email-templatesreact-componentshtml-emailstransactional-emails

Repository

resend/react-email

Skill path: skills

React Email provides React components for building HTML emails that work across email clients. It offers core structure components, content elements, and specialized features like Tailwind support. The skill includes examples for welcome emails, newsletters, and team invitations with proper TypeScript typing and inline styling.

Open repository

Best for

Primary workflow: Write Technical Docs.

Technical facets: Frontend, Full Stack, Tech Writer.

Target audience: Frontend developers building transactional emails, product teams creating email templates, developers working with email service providers like Resend.

License: MIT.

Original source

Catalog source: SkillHub Club.

Repository owner: resend.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install react-email into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/resend/react-email before adding react-email to shared team environments
  • Use react-email for frontend workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: react-email
description: Create beautiful, responsive HTML emails using React components with React Email. Build transactional emails with modern components, support internationalization, and integrate with email service providers like Resend. Use when creating welcome emails, password resets, notifications, order confirmations, or any HTML email templates.
license: MIT
metadata:
  author: Resend
  repository: https://github.com/resend/react-email
---

# React Email

Build and send HTML emails using React components - a modern, component-based approach to email development that works across all major email clients.

## Quick Start

Install React Email components:

```bash
npm install @react-email/components -E
```

## Basic Email Template

Create an email component with proper structure:

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

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

export default function WelcomeEmail({ name, verificationUrl }: WelcomeEmailProps) {
  return (
    <Html lang="en">
      <Head />
      <Preview>Welcome - Verify your email</Preview>
      <Body style={{ backgroundColor: '#f6f9fc', fontFamily: 'Arial, sans-serif' }}>
        <Container style={{ maxWidth: '600px', margin: '0 auto', padding: '20px' }}>
          <Heading style={{ fontSize: '24px', color: '#333' }}>
            Welcome!
          </Heading>
          <Text style={{ fontSize: '16px', color: '#333' }}>
            Hi {name}, thanks for signing up!
          </Text>
          <Button
            href={verificationUrl}
            style={{
              backgroundColor: '#007bff',
              color: '#fff',
              padding: '12px 20px',
              borderRadius: '4px',
              textDecoration: 'none',
              display: 'block',
              textAlign: 'center'
            }}
          >
            Verify Email
          </Button>
        </Container>
      </Body>
    </Html>
  );
}

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

export { WelcomeEmail };
```

## Essential Components

See [references/COMPONENTS.md](references/COMPONENTS.md) for complete component documentation.

**Core Structure:**
- `Html` - Root wrapper with `lang` attribute
- `Head` - Meta elements, styles, fonts
- `Body` - Main content wrapper
- `Container` - Centers content (max-width layout)
- `Section` - Layout sections
- `Row` & `Column` - Multi-column layouts

**Content:**
- `Preview` - Inbox preview text, always first in `Body`
- `Heading` - h1-h6 headings
- `Text` - Paragraphs
- `Button` - Styled link buttons
- `Link` - Hyperlinks
- `Img` - Images (use absolute URLs)
- `Hr` - Horizontal dividers

**Specialized:**
- `CodeBlock` - Syntax-highlighted code
- `CodeInline` - Inline code
- `Markdown` - Render markdown
- `Font` - Custom web fonts
- `Tailwind` - Tailwind CSS support

## Rendering and Sending

### Convert to HTML

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

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

### Send with Resend (Recommended)

**Method 1: MCP Tool**

When you have access to the Resend MCP tool:

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

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

// Create plain text version
const text = `Welcome!\n\nHi John, thanks for signing up!\n\nVerify: https://example.com/verify`;

// Use Resend MCP send-email tool with:
// - to: [email protected]
// - subject: Welcome to Acme
// - html: <rendered html>
// - text: <plain text version>
```

**Method 2: Resend SDK with React**

The most convenient method - pass React components directly:

```tsx
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 <[email protected]>',
  to: ['[email protected]'],
  subject: 'Welcome to Acme',
  react: <WelcomeEmail name="John" verificationUrl="https://example.com/verify" />
});

if (error) {
  console.error('Failed to send:', error);
}
```

This handles the plain-text rendering and HTML rendering for you.

### Send with Other Providers

**Nodemailer:**

```tsx
import { render } from '@react-email/components';
import nodemailer from 'nodemailer';

const transporter = nodemailer.createTransport({
  host: 'smtp.example.com',
  port: 587,
  auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS }
});

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

await transporter.sendMail({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Welcome',
  html
});
```

**SendGrid:**

```tsx
import { render } from '@react-email/components';
import sgMail from '@sendgrid/mail';

sgMail.setApiKey(process.env.SENDGRID_API_KEY);

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

await sgMail.send({
  to: '[email protected]',
  from: '[email protected]',
  subject: 'Welcome',
  html
});
```

## Internationalization

See [references/I18N.md](references/I18N.md) for complete i18n documentation.

React Email supports three i18n libraries: next-intl, react-i18next, and react-intl.

### Quick Example (next-intl)

```tsx
import { createTranslator } from 'next-intl';
import { Html, Body, Container, Text, Button } from '@react-email/components';

interface EmailProps {
  name: string;
  locale: string;
}

export default async function WelcomeEmail({ name, locale }: EmailProps) {
  const t = createTranslator({
    messages: await import(`../messages/${locale}.json`),
    namespace: 'welcome-email',
    locale
  });

  return (
    <Html lang={locale}>
      <Body>
        <Container>
          <Text>{t('greeting')} {name},</Text>
          <Text>{t('body')}</Text>
          <Button href="https://example.com">{t('cta')}</Button>
        </Container>
      </Body>
    </Html>
  );
}
```

Message files (`messages/en.json`, `messages/es.json`, etc.):

```json
{
  "welcome-email": {
    "greeting": "Hi",
    "body": "Thanks for signing up!",
    "cta": "Get Started"
  }
}
```

## Email Best Practices

1. **Always use inline styles** - Email clients have poor CSS class support. Use the `style` prop on all components. The `Tailwind` component automatically inlines styles.

2. **Test across email clients** - Test in Gmail, Outlook, Apple Mail, Yahoo Mail. Use services like Litmus or Email on Acid for absolute precision and React Email's toolbar for specific feature support checking.

3. **Keep it responsive** - Max-width around 600px, test on mobile devices.

4. **Use absolute image URLs** - Host on reliable CDN, always include `alt` text.

5. **Provide plain text version** - Required for accessibility and some email clients.

6. **Keep file size under 102KB** - Gmail clips larger emails.

7. **Add proper TypeScript types** - Define interfaces for all email props.

8. **Include preview props** - Add `.PreviewProps` to components for development testing.

9. **Handle errors** - Always check for errors when sending emails.

10. **Use verified domains** - For production, use verified domains in `from` addresses.

## Common Patterns

See [references/PATTERNS.md](references/PATTERNS.md) for complete examples including:
- Password reset emails
- Order confirmations with product lists
- Notification emails with code blocks
- Multi-column layouts
- Email templates with custom fonts

## Additional Resources

- [React Email Documentation](https://react.email)
- [React Email GitHub](https://github.com/resend/react-email)
- [Resend Documentation](https://resend.com/docs)
- [Email Client CSS Support](https://www.caniemail.com)
- Component Reference: [references/COMPONENTS.md](references/COMPONENTS.md)
- Internationalization Guide: [references/I18N.md](references/I18N.md)
- Common Patterns: [references/PATTERNS.md](references/PATTERNS.md)


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### references/COMPONENTS.md

```markdown
# React Email Components Reference

Complete reference for all React Email components.

## Structural Components

### Html

Root wrapper for the email. Always use as the outermost component.

```jsx
import { Html } from '@react-email/components';

<Html lang="en" dir="ltr">
  {/* email content */}
</Html>
```

**Props:**
- `lang` - Language code (e.g., "en", "es", "fr")
- `dir` - Text direction ("ltr" or "rtl")

### Head

Contains meta elements, styles, and fonts. If using Tailwind, should be wrapped by `<Tailwind>`.

```jsx
import { Head } from '@react-email/components';

<Head>
  <title>Email Title</title>
</Head>
```

### Body

Main email body wrapper.

```jsx
import { Body } from '@react-email/components';

<Body style={{ backgroundColor: '#f6f9fc', fontFamily: 'Arial, sans-serif' }}>
  {/* email content */}
</Body>
```

### Container

Centers email content using a table, and has a max-width constraint of `37.5em`.

```jsx
import { Container } from '@react-email/components';

<Container>
  {/* centered content */}
</Container>
```

### Section

Layout section that can contain rows and columns.

```jsx
import { Section } from '@react-email/components';

<Section style={{ padding: '20px', backgroundColor: '#fff' }}>
  {/* section content */}
</Section>
```

### Row & Column

Multi-column layouts using table-based rendering.

```jsx
import { Row, Column } from '@react-email/components';

<Section>
  <Row>
    <Column style={{ width: '50%', padding: '10px' }}>
      Left column content
    </Column>
    <Column style={{ width: '50%', padding: '10px' }}>
      Right column content
    </Column>
  </Row>
</Section>
```

**Column widths:**
- Always define both the `width` HTML attribute and the `width` style attribute
- Use percentage widths (e.g., "50%", "33.33%")
- Or fixed pixel widths (e.g., "200px")
- Total should add up to 100% or container width

## Content Components

### Preview

Preview text shown in email inbox before opening.

```jsx
import { Preview } from '@react-email/components';

<Preview>Welcome to our platform - Get started today!</Preview>
```

**Best practices:**
- Keep under 140 characters
- Make it compelling and action-oriented
- Should always be the first element inside `<Body>`

### Heading

Heading text (h1-h6).

```jsx
import { Heading } from '@react-email/components';

<Heading as="h1" style={{ fontSize: '24px', fontWeight: 'bold', color: '#333' }}>
  Welcome to Acme
</Heading>

<Heading as="h2" style={{ fontSize: '20px', fontWeight: '600', color: '#666' }}>
  Getting Started
</Heading>
```

**Props:**
- `as` - HTML heading level ("h1" through "h6")

### Text

Paragraph text component.

```jsx
import { Text } from '@react-email/components';

<Text style={{ fontSize: '16px', lineHeight: '24px', color: '#333' }}>
  Your paragraph content here.
</Text>
```

### Button

Styled link that looks like a button. Has work around for padding issues in Outlook.

```jsx
import { Button } from '@react-email/components';

<Button 
  href="https://example.com/verify"
  target="_blank"
  style={{ 
    backgroundColor: '#007bff', 
    color: '#ffffff',
    padding: '12px 20px',
    borderRadius: '4px',
    textDecoration: 'none',
    textAlign: 'center',
    display: 'block'
  }}
>
  Verify Email Address
</Button>
```

**Props:**
- `href` (required) - URL to link to
- `target` - Default is "_blank"

**Styling tips:**
- Always set `display: block` for full-width buttons
- Use `textAlign: center` for centered text
- Set explicit `backgroundColor` and `color`
- Add `textDecoration: none` to remove underline

### Link

Standard hyperlink.

```jsx
import { Link } from '@react-email/components';

<Link href="https://example.com" target="_blank" style={{ color: '#007bff' }}>
  Visit our website
</Link>
```

**Props:**
- `href` (required) - URL to link to
- `target` - Default is "_blank"

### Img

Image component.

```jsx
import { Img } from '@react-email/components';

<Img 
  src="https://example.com/logo.png" 
  alt="Company Logo"
  width="150"
  height="50"
  style={{ display: 'block', margin: '0 auto' }}
/>
```

**Props:**
- `src` (required) - Image URL (must be absolute)
- `alt` (required) - Alt text for accessibility
- `width` - Image width in pixels
- `height` - Image height in pixels

**Best practices:**
- Always use absolute URLs hosted on CDN
- Always include alt text
- Specify width and height to prevent layout shift
- Use `display: block` to avoid spacing issues

### Hr

Horizontal divider line.

```jsx
import { Hr } from '@react-email/components';

<Hr style={{ borderColor: '#e6e6e6', margin: '20px 0' }} />
```

## Specialized Components

### CodeBlock

Syntax-highlighted code blocks using Prism.js.

```jsx
import { CodeBlock, dracula } from '@react-email/components';

<CodeBlock
  code={`const greeting = "Hello World";
console.log(greeting);`}
  language="javascript"
  theme={dracula}
  lineNumbers
/>
```

**Props:**
- `code` (required) - Code string to display
- `language` (required) - Programming language (e.g., "javascript", "python", "typescript")
- `theme` - (required) Prism theme (dracula, github, etc.)
- `lineNumbers` - Boolean to show line numbers

**Available themes:**
Import from `@react-email/components`: dracula, github, nord, etc.

### CodeInline

Inline code within text.

```jsx
import { CodeInline } from '@react-email/components';

<Text>
  Run <CodeInline>npm install</CodeInline> to get started.
</Text>
```

### Markdown

Render Markdown content as HTML.

```jsx
import { Markdown } from '@react-email/components';

<Markdown
  markdownCustomStyles={{
    h1: { color: '#333', fontSize: '24px' },
    h2: { color: '#666', fontSize: '20px' },
    p: { fontSize: '16px', lineHeight: '24px' },
    a: { color: '#007bff' },
    code: { backgroundColor: '#f4f4f4', padding: '2px 4px' }
  }}
  markdownContainerStyles={{
    padding: '20px',
    backgroundColor: '#fff'
  }}
>
{`# Hello World

This is **bold** and this is *italic*.

- List item 1
- List item 2

[Link text](https://example.com)

\`inline code\`

\`\`\`javascript
const code = "block";
\`\`\`
`}
</Markdown>
```

**Props:**
- `children` (required) - Markdown string
- `markdownCustomStyles` - Style overrides for HTML elements
- `markdownContainerStyles` - Styles for container div

### Font

Custom web fonts.

```jsx
import { Font } from '@react-email/components';

<Head>
  <Font
    fontFamily="Roboto"
    fallbackFontFamily="Arial, sans-serif"
    webFont={{
      url: "https://fonts.gstatic.com/s/roboto/v27/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2",
      format: "woff2"
    }}
  />
</Head>
```

**Props:**
- `fontFamily` (required) - Font family name
- `fallbackFontFamily` - Fallback fonts
- `webFont` - Object with `url` and `format`

**Supported formats:**
- woff2 (recommended)
- woff
- truetype
- opentype

### Tailwind

Use Tailwind CSS utility classes.

```jsx
import { Tailwind, pixelBasedPreset } from '@react-email/components';

<Tailwind
  config={{
    presets: [pixelBasedPreset],
    theme: {
      extend: {
        colors: {
          brand: '#007bff',
          accent: '#28a745'
        },
        spacing: {
          '128': '32rem'
        }
      }
    }
  }}
>
  <Container className="max-w-2xl mx-auto p-4">
    <Heading className="text-2xl font-bold text-brand mb-4">
      Welcome!
    </Heading>
    <Text className="text-base text-gray-700 mb-4">
      Your content here.
    </Text>
    <Button className="bg-brand text-white px-6 py-3 rounded-lg">
      Get Started
    </Button>
  </Container>
</Tailwind>
```

**Props:**
- `config` - Tailwind configuration object

**How it works:**
- Tailwind classes are converted to inline styles automatically
- Media queries are extracted to `<style>` tag in `<head>`
- CSS variables are resolved
- RGB color syntax is normalized for email client compatibility

**Best practices:**
- Use with care as it can increase render times and bundle size significantly
- Wrap your entire email content in `<Tailwind>`
- Custom config is optional - defaults work well
- Responsive classes (sm:, md:, lg:) work via media queries, but should be used with caution due to limited email client support 

```

### references/I18N.md

```markdown
# Internationalization (i18n) Guide

Complete guide for implementing multi-language email support with React Email.

React Email officially supports three popular i18n libraries: next-intl, react-i18next, and react-intl.

## next-intl

Best choice for Next.js applications with straightforward API.

### Installation

```bash
npm install next-intl
```

### Setup

**1. Create message files:**

```json
// messages/en.json
{
  "welcome-email": {
    "subject": "Welcome to Acme",
    "greeting": "Hi",
    "body": "Thanks for signing up! We're excited to have you on board.",
    "cta": "Get Started",
    "footer": "If you have questions, reply to this email."
  }
}
```

```json
// messages/es.json
{
  "welcome-email": {
    "subject": "Bienvenido a Acme",
    "greeting": "Hola",
    "body": "¡Gracias por registrarte! Estamos emocionados de tenerte en la plataforma.",
    "cta": "Comenzar",
    "footer": "Si tienes preguntas, responde a este correo electrónico."
  }
}
```

```json
// messages/fr.json
{
  "welcome-email": {
    "subject": "Bienvenue chez Acme",
    "greeting": "Bonjour",
    "body": "Merci de vous être inscrit ! Nous sommes ravis de vous accueillir.",
    "cta": "Commencer",
    "footer": "Si vous avez des questions, répondez à cet e-mail."
  }
}
```

**2. Update email template:**

```tsx
import { createTranslator } from 'next-intl';
import {
  Html,
  Head,
  Preview,
  Body,
  Container,
  Heading,
  Text,
  Button,
  Hr
} from '@react-email/components';

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

export default async function WelcomeEmail({
  name,
  verificationUrl,
  locale
}: WelcomeEmailProps) {
  const t = createTranslator({
    messages: await import(`../messages/${locale}.json`),
    namespace: 'welcome-email',
    locale
  });

  return (
    <Html lang={locale}>
      <Head />
      <Preview>{t('subject')}</Preview>
      <Body style={main}>
        <Container style={container}>
          <Heading style={h1}>{t('subject')}</Heading>
          <Text style={text}>{t('greeting')} {name},</Text>
          <Text style={text}>{t('body')}</Text>
          <Button href={verificationUrl} style={button}>
            {t('cta')}
          </Button>
          <Hr style={hr} />
          <Text style={footer}>{t('footer')}</Text>
        </Container>
      </Body>
    </Html>
  );
}

// Preview props
WelcomeEmail.PreviewProps = {
  name: 'John',
  verificationUrl: 'https://example.com/verify',
  locale: 'en'
} as WelcomeEmailProps;

// Styles
const main = { backgroundColor: '#f6f9fc', fontFamily: 'Arial, sans-serif' };
const container = { margin: '0 auto', padding: '40px 20px', maxWidth: '600px' };
const h1 = { fontSize: '24px', fontWeight: 'bold', color: '#333' };
const text = { fontSize: '16px', lineHeight: '26px', color: '#333', margin: '16px 0' };
const button = {
  backgroundColor: '#007bff',
  color: '#fff',
  padding: '12px 20px',
  borderRadius: '4px',
  textDecoration: 'none',
  textAlign: 'center' as const,
  display: 'block'
};
const hr = { borderColor: '#e6ebf1', margin: '20px 0' };
const footer = { fontSize: '14px', color: '#8898aa' };
```

**3. Send with locale:**

```tsx
await resend.emails.send({
  from: 'Acme <[email protected]>',
  to: ['[email protected]'],
  subject: 'Welcome',
  react: <WelcomeEmail name="Jean" verificationUrl="..." locale="fr" />
});
```

## react-intl (FormatJS)

Good choice for complex formatting needs (plurals, dates, numbers).

### Installation

```bash
npm install react-intl
```

### Setup

**1. Create message files:**

```json
// messages/en/welcome-email.json
{
  "header": "Welcome to Acme",
  "greeting": "Hi",
  "body": "Thanks for signing up!",
  "cta": "Get Started",
  "itemCount": "{count, plural, one {# item} other {# items}}"
}
```

**2. Use in email:**

```tsx
import { createIntl } from 'react-intl';
import { Html, Body, Container, Text, Button } from '@react-email/components';

interface WelcomeEmailProps {
  name: string;
  locale: string;
  itemCount?: number;
}

export default async function WelcomeEmail({
  name,
  locale,
  itemCount = 1
}: WelcomeEmailProps) {
  const { formatMessage } = createIntl({
    locale,
    messages: await import(`../messages/${locale}/welcome-email.json`)
  });

  return (
    <Html lang={locale}>
      <Body>
        <Container>
          <Text>{formatMessage({ id: 'greeting' })} {name},</Text>
          <Text>{formatMessage({ id: 'body' })}</Text>
          <Text>
            {formatMessage({ id: 'itemCount' }, { count: itemCount })}
          </Text>
          <Button href="https://example.com">
            {formatMessage({ id: 'cta' })}
          </Button>
        </Container>
      </Body>
    </Html>
  );
}
```

## react-i18next

Best for non-Next.js applications or when you need more control.

### Installation

```bash
npm install react-i18next i18next i18next-resources-to-backend
```

### Setup

**1. Configure i18next:**

```js
// i18n.js
import i18next from 'i18next';
import resourcesToBackend from 'i18next-resources-to-backend';
import { initReactI18next } from 'react-i18next';

i18next
  .use(initReactI18next)
  .use(resourcesToBackend((language, namespace) =>
    import(`./messages/${language}/${namespace}.json`)
  ))
  .init({
    supportedLngs: ['en', 'es', 'fr', 'de'],
    fallbackLng: 'en',
    lng: undefined,
    preload: ['en', 'es', 'fr', 'de']
  });

export { i18next };
```

**2. Create translation helper:**

```js
// get-t.js
import { i18next } from './i18n';

export async function getT(namespace, locale) {
  if (locale && i18next.resolvedLanguage !== locale) {
    await i18next.changeLanguage(locale);
  }
  if (namespace && !i18next.hasLoadedNamespace(namespace)) {
    await i18next.loadNamespaces(namespace);
  }
  return {
    t: i18next.getFixedT(
      locale ?? i18next.resolvedLanguage,
      Array.isArray(namespace) ? namespace[0] : namespace
    ),
    i18n: i18next
  };
}
```

**3. Create message files:**

```json
// messages/en/welcome-email.json
{
  "subject": "Welcome to Acme",
  "greeting": "Hi",
  "body": "Thanks for signing up!",
  "cta": "Get Started"
}
```

```json
// messages/es/welcome-email.json
{
  "subject": "Bienvenido a Acme",
  "greeting": "Hola",
  "body": "¡Gracias por registrarte!",
  "cta": "Comenzar"
}
```

**4. Use in email template:**

```tsx
import { getT } from '../get-t';
import { Html, Body, Container, Heading, Text, Button } from '@react-email/components';

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

export default async function WelcomeEmail({ name, locale }: WelcomeEmailProps) {
  const { t } = await getT('welcome-email', locale);

  return (
    <Html lang={locale}>
      <Body>
        <Container>
          <Heading>{t('subject')}</Heading>
          <Text>{t('greeting')} {name},</Text>
          <Text>{t('body')}</Text>
          <Button href="https://example.com">{t('cta')}</Button>
        </Container>
      </Body>
    </Html>
  );
}
```


## Message File Organization

### By Namespace (Recommended)

Organize translations by email template:

```
messages/
├── en.json          # All English translations
│   ├── welcome-email
│   ├── password-reset
│   └── order-confirmation
├── es.json          # All Spanish translations
└── fr.json          # All French translations
```

Or organize by template with separate files:

```
messages/
├── en/
│   ├── welcome-email.json
│   ├── password-reset.json
│   └── order-confirmation.json
├── es/
│   ├── welcome-email.json
│   ├── password-reset.json
│   └── order-confirmation.json
└── fr/
    ├── welcome-email.json
    ├── password-reset.json
    └── order-confirmation.json
```

### Translation Keys

Use descriptive, hierarchical keys:

```json
{
  "welcome-email": {
    "subject": "Welcome!",
    "preview": "Get started with your account",
    "header": {
      "title": "Welcome to Acme",
      "subtitle": "We're glad you're here"
    },
    "body": {
      "greeting": "Hi",
      "intro": "Thanks for signing up!",
      "next-steps": "Here's how to get started:"
    },
    "cta": {
      "primary": "Get Started",
      "secondary": "Learn More"
    },
    "footer": {
      "help": "Need help? Reply to this email",
      "unsubscribe": "Unsubscribe from these emails"
    }
  }
}
```

## Best Practices

### 1. Always Pass Locale

Make locale a required prop:

```tsx
interface EmailProps {
  locale: string;
  // other props...
}
```

### 2. Set HTML Lang Attribute

```tsx
<Html lang={locale}>
```

### 3. Support RTL Languages

For Arabic, Hebrew, etc.:

```tsx
const isRTL = ['ar', 'he', 'fa'].includes(locale);

<Html lang={locale} dir={isRTL ? 'rtl' : 'ltr'}>
```

### 4. Fallback Values

Provide fallback translations:

```tsx
const t = createTranslator({
  messages: await import(`../messages/${locale}.json`).catch(() =>
    import('../messages/en.json')
  ),
  locale,
  namespace: 'welcome-email'
});
```

### 5. Test All Locales

Test email rendering for each supported locale:

```tsx
WelcomeEmail.PreviewProps = {
  name: 'Test User',
  locale: 'en'  // Change to test different locales
} as WelcomeEmailProps;
```

### 6. Keep Keys Consistent

Use the same translation keys across all locale files:

```json
// ✅ Good
// en.json: { "cta": "Get Started" }
// es.json: { "cta": "Comenzar" }

// ❌ Bad
// en.json: { "button": "Get Started" }
// es.json: { "cta": "Comenzar" }
```

### 7. Handle Missing Translations

Set up fallback behavior:

```tsx
// With next-intl
const t = createTranslator({
  messages,
  locale,
  namespace: 'welcome-email',
  onError: (error) => {
    console.warn('Translation missing:', error);
  }
});
```

### 8. Subject Line Translation

Don't forget to translate email subjects:

```tsx
const t = createTranslator({...});

await resend.emails.send({
  from: 'Acme <[email protected]>',
  to: [user.email],
  subject: t('subject'),  // ✅ Translated subject
  react: <WelcomeEmail {...props} />
});
```

### 9. Format Consistency

Maintain consistent formatting across locales:
- Date formats (MM/DD/YYYY vs DD/MM/YYYY)
- Time formats (12h vs 24h)
- Number separators (1,234.56 vs 1.234,56)
- Currency symbols and placement ($100 vs 100$)

Use `Intl` APIs for automatic locale-specific formatting.

## Example: Complete Multi-locale Email

```tsx
import { createTranslator } from 'next-intl';
import {
  Html,
  Head,
  Preview,
  Body,
  Container,
  Section,
  Heading,
  Text,
  Button,
  Hr
} from '@react-email/components';

interface OrderConfirmationProps {
  orderNumber: string;
  total: number;
  currency: string;
  locale: string;
  orderDate: Date;
}

export default async function OrderConfirmation({
  orderNumber,
  total,
  currency,
  locale,
  orderDate
}: OrderConfirmationProps) {
  const t = createTranslator({
    messages: await import(`../messages/${locale}.json`),
    namespace: 'order-confirmation',
    locale
  });

  const isRTL = ['ar', 'he'].includes(locale);

  const currencyFormatter = new Intl.NumberFormat(locale, {
    style: 'currency',
    currency
  });

  const dateFormatter = new Intl.DateTimeFormat(locale, {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  });

  return (
    <Html lang={locale} dir={isRTL ? 'rtl' : 'ltr'}>
      <Head />
      <Preview>{t('preview')}</Preview>
      <Body style={main}>
        <Container style={container}>
          <Heading style={h1}>{t('title')}</Heading>
          <Text style={text}>
            {t('order-number')}: {orderNumber}
          </Text>
          <Text style={text}>
            {t('order-date')}: {dateFormatter.format(orderDate)}
          </Text>
          <Section style={section}>
            <Text style={totalText}>
              {t('total')}: {currencyFormatter.format(total)}
            </Text>
          </Section>
          <Button href={`https://example.com/orders/${orderNumber}`} style={button}>
            {t('view-order')}
          </Button>
          <Hr style={hr} />
          <Text style={footer}>{t('footer')}</Text>
        </Container>
      </Body>
    </Html>
  );
}

const main = { backgroundColor: '#f6f9fc', fontFamily: 'Arial, sans-serif' };
const container = { margin: '0 auto', padding: '40px 20px', maxWidth: '600px' };
const h1 = { fontSize: '24px', fontWeight: 'bold', color: '#333' };
const text = { fontSize: '16px', color: '#333', margin: '8px 0' };
const section = { backgroundColor: '#fff', padding: '20px', borderRadius: '4px' };
const totalText = { fontSize: '20px', fontWeight: 'bold', color: '#333' };
const button = {
  backgroundColor: '#007bff',
  color: '#fff',
  padding: '12px 20px',
  borderRadius: '4px',
  textDecoration: 'none',
  textAlign: 'center' as const,
  display: 'block',
  margin: '20px 0'
};
const hr = { borderColor: '#e6ebf1', margin: '20px 0' };
const footer = { fontSize: '14px', color: '#8898aa' };
```

With message files:

```json
// messages/en.json
{
  "order-confirmation": {
    "preview": "Your order has been confirmed",
    "title": "Order Confirmed",
    "order-number": "Order number",
    "order-date": "Order date",
    "total": "Total",
    "view-order": "View Order",
    "footer": "Thank you for your purchase!"
  }
}
```

```json
// messages/es.json
{
  "order-confirmation": {
    "preview": "Tu pedido ha sido confirmado",
    "title": "Pedido Confirmado",
    "order-number": "Número de pedido",
    "order-date": "Fecha del pedido",
    "total": "Total",
    "view-order": "Ver Pedido",
    "footer": "¡Gracias por tu compra!"
  }
}
```

```

### references/PATTERNS.md

```markdown
# Common Email Patterns

Real-world examples of common email templates using React Email.

## Password Reset Email

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

interface PasswordResetProps {
  resetUrl: string;
  email: string;
  expiryHours?: number;
}

export default function PasswordReset({ resetUrl, email, expiryHours = 1 }: PasswordResetProps) {
  return (
    <Html lang="en">
      <Head />
      <Preview>Reset your password - Action required</Preview>
      <Body style={main}>
        <Container style={container}>
          <Heading style={h1}>Reset Your Password</Heading>
          <Text style={text}>
            A password reset was requested for your account: <strong>{email}</strong>
          </Text>
          <Text style={text}>
            Click the button below to reset your password. This link expires in {expiryHours} hour{expiryHours > 1 ? 's' : ''}.
          </Text>
          <Button href={resetUrl} style={button}>
            Reset Password
          </Button>
          <Hr style={hr} />
          <Text style={footer}>
            If you didn't request this, please ignore this email. Your password will remain unchanged.
          </Text>
          <Text style={footer}>
            For security, this link will only work once.
          </Text>
        </Container>
      </Body>
    </Html>
  );
}

PasswordReset.PreviewProps = {
  resetUrl: 'https://example.com/reset/abc123',
  email: '[email protected]',
  expiryHours: 1
} as PasswordResetProps;

const main = { backgroundColor: '#f6f9fc', fontFamily: 'Arial, sans-serif' };
const container = { margin: '0 auto', padding: '40px 20px', maxWidth: '560px', backgroundColor: '#ffffff' };
const h1 = { fontSize: '24px', fontWeight: 'bold', color: '#333', marginBottom: '20px' };
const text = { fontSize: '16px', lineHeight: '26px', color: '#333', margin: '16px 0' };
const button = {
  backgroundColor: '#dc3545',
  color: '#fff',
  padding: '14px 28px',
  borderRadius: '4px',
  textDecoration: 'none',
  textAlign: 'center' as const,
  display: 'block',
  fontWeight: 'bold',
  margin: '24px 0'
};
const hr = { borderColor: '#e6ebf1', margin: '24px 0' };
const footer = { fontSize: '14px', color: '#8898aa', lineHeight: '20px', margin: '8px 0' };
```

## Order Confirmation with Product List

```tsx
import { 
  Html, Head, Preview, Body, Container, Section, Row, Column, 
  Heading, Text, Img, Hr 
} from '@react-email/components';

interface Product {
  name: string;
  price: number;
  quantity: number;
  image: string;
  sku?: string;
}

interface OrderConfirmationProps {
  orderNumber: string;
  orderDate: Date;
  items: Product[];
  subtotal: number;
  shipping: number;
  tax: number;
  total: number;
  shippingAddress: {
    name: string;
    street: string;
    city: string;
    state: string;
    zip: string;
    country: string;
  };
}

export default function OrderConfirmation({
  orderNumber,
  orderDate,
  items,
  subtotal,
  shipping,
  tax,
  total,
  shippingAddress
}: OrderConfirmationProps) {
  return (
    <Html lang="en">
      <Head />
      <Preview>Order #{orderNumber} confirmed - Thank you for your purchase!</Preview>
      <Body style={main}>
        <Container style={container}>
          <Heading style={h1}>Order Confirmed</Heading>
          <Text style={text}>Thank you for your order!</Text>
          
          <Section style={infoSection}>
            <Row>
              <Column>
                <Text style={label}>Order Number</Text>
                <Text style={value}>#{orderNumber}</Text>
              </Column>
              <Column>
                <Text style={label}>Order Date</Text>
                <Text style={value}>{orderDate.toLocaleDateString()}</Text>
              </Column>
            </Row>
          </Section>

          <Hr style={hr} />

          <Heading as="h2" style={h2}>Order Items</Heading>
          
          {items.map((item, index) => (
            <Section key={index} style={productSection}>
              <Row>
                <Column style={{ width: '80px', verticalAlign: 'top' }}>
                  <Img 
                    src={item.image} 
                    alt={item.name}
                    width="80" 
                    height="80"
                    style={productImage}
                  />
                </Column>
                <Column style={{ verticalAlign: 'top', paddingLeft: '16px' }}>
                  <Text style={productName}>{item.name}</Text>
                  {item.sku && <Text style={productSku}>SKU: {item.sku}</Text>}
                  <Text style={productDetails}>
                    Quantity: {item.quantity} × ${item.price.toFixed(2)}
                  </Text>
                </Column>
                <Column style={{ width: '100px', textAlign: 'right', verticalAlign: 'top' }}>
                  <Text style={productPrice}>
                    ${(item.quantity * item.price).toFixed(2)}
                  </Text>
                </Column>
              </Row>
            </Section>
          ))}

          <Hr style={hr} />

          <Section style={totalsSection}>
            <Row>
              <Column><Text style={totalsLabel}>Subtotal</Text></Column>
              <Column style={{ textAlign: 'right' }}>
                <Text style={totalsValue}>${subtotal.toFixed(2)}</Text>
              </Column>
            </Row>
            <Row>
              <Column><Text style={totalsLabel}>Shipping</Text></Column>
              <Column style={{ textAlign: 'right' }}>
                <Text style={totalsValue}>${shipping.toFixed(2)}</Text>
              </Column>
            </Row>
            <Row>
              <Column><Text style={totalsLabel}>Tax</Text></Column>
              <Column style={{ textAlign: 'right' }}>
                <Text style={totalsValue}>${tax.toFixed(2)}</Text>
              </Column>
            </Row>
            <Hr style={thinHr} />
            <Row>
              <Column><Text style={totalLabel}>Total</Text></Column>
              <Column style={{ textAlign: 'right' }}>
                <Text style={totalValue}>${total.toFixed(2)}</Text>
              </Column>
            </Row>
          </Section>

          <Hr style={hr} />

          <Heading as="h2" style={h2}>Shipping Address</Heading>
          <Section style={addressSection}>
            <Text style={addressText}>{shippingAddress.name}</Text>
            <Text style={addressText}>{shippingAddress.street}</Text>
            <Text style={addressText}>
              {shippingAddress.city}, {shippingAddress.state} {shippingAddress.zip}
            </Text>
            <Text style={addressText}>{shippingAddress.country}</Text>
          </Section>

          <Text style={footer}>
            Questions about your order? Reply to this email and we'll help you out.
          </Text>
        </Container>
      </Body>
    </Html>
  );
}

OrderConfirmation.PreviewProps = {
  orderNumber: '10234',
  orderDate: new Date(),
  items: [
    {
      name: 'Vintage Macintosh',
      price: 499.00,
      quantity: 1,
      image: 'https://via.placeholder.com/80',
      sku: 'MAC-001'
    },
    {
      name: 'Mechanical Keyboard',
      price: 149.99,
      quantity: 2,
      image: 'https://via.placeholder.com/80',
      sku: 'KEY-042'
    }
  ],
  subtotal: 798.98,
  shipping: 15.00,
  tax: 69.42,
  total: 883.40,
  shippingAddress: {
    name: 'John Doe',
    street: '123 Main St',
    city: 'San Francisco',
    state: 'CA',
    zip: '94102',
    country: 'USA'
  }
} as OrderConfirmationProps;

const main = { backgroundColor: '#f6f9fc', fontFamily: 'Arial, sans-serif' };
const container = { margin: '0 auto', padding: '40px 20px', maxWidth: '600px' };
const h1 = { fontSize: '28px', fontWeight: 'bold', color: '#333', marginBottom: '8px' };
const h2 = { fontSize: '20px', fontWeight: 'bold', color: '#333', margin: '24px 0 16px 0' };
const text = { fontSize: '16px', color: '#666', marginBottom: '24px' };
const infoSection = { backgroundColor: '#f8f9fa', padding: '16px', borderRadius: '4px', marginBottom: '24px' };
const label = { fontSize: '12px', color: '#666', textTransform: 'uppercase' as const, marginBottom: '4px' };
const value = { fontSize: '16px', fontWeight: 'bold', color: '#333', margin: '0' };
const hr = { borderColor: '#e6ebf1', margin: '24px 0' };
const thinHr = { borderColor: '#e6ebf1', margin: '12px 0' };
const productSection = { marginBottom: '16px' };
const productImage = { borderRadius: '4px', border: '1px solid #e6ebf1' };
const productName = { fontSize: '16px', fontWeight: 'bold', color: '#333', margin: '0 0 4px 0' };
const productSku = { fontSize: '14px', color: '#999', margin: '0 0 8px 0' };
const productDetails = { fontSize: '14px', color: '#666', margin: '0' };
const productPrice = { fontSize: '16px', fontWeight: 'bold', color: '#333', margin: '0' };
const totalsSection = { marginTop: '24px' };
const totalsLabel = { fontSize: '14px', color: '#666', margin: '8px 0' };
const totalsValue = { fontSize: '14px', color: '#333', margin: '8px 0' };
const totalLabel = { fontSize: '18px', fontWeight: 'bold', color: '#333', margin: '8px 0' };
const totalValue = { fontSize: '18px', fontWeight: 'bold', color: '#333', margin: '8px 0' };
const addressSection = { backgroundColor: '#f8f9fa', padding: '16px', borderRadius: '4px' };
const addressText = { fontSize: '14px', color: '#333', margin: '4px 0' };
const footer = { fontSize: '14px', color: '#8898aa', marginTop: '32px' };
```

## Notification Email with Code Block

```tsx
import { 
  Html, Head, Preview, Body, Container, Heading, Text, 
  CodeBlock, dracula, Hr, Link 
} from '@react-email/components';

interface NotificationProps {
  title: string;
  message: string;
  severity: 'info' | 'warning' | 'error' | 'success';
  timestamp: Date;
  logData?: string;
  actionUrl?: string;
  actionLabel?: string;
}

export default function Notification({
  title,
  message,
  severity,
  timestamp,
  logData,
  actionUrl,
  actionLabel = 'View Details'
}: NotificationProps) {
  const severityColors = {
    info: '#0ea5e9',
    warning: '#f59e0b',
    error: '#ef4444',
    success: '#22c55e'
  };

  const severityColor = severityColors[severity];

  return (
    <Html lang="en">
      <Head />
      <Preview>{title} - {severity}</Preview>
      <Body style={main}>
        <Container style={container}>
          <Section style={{ ...statusBar, backgroundColor: severityColor }} />
          
          <Heading style={h1}>{title}</Heading>
          
          <Text style={{ ...badge, backgroundColor: severityColor }}>
            {severity.toUpperCase()}
          </Text>
          
          <Text style={text}>{message}</Text>
          
          <Text style={timestamp}>
            {new Date(timestamp).toLocaleString('en-US', {
              dateStyle: 'long',
              timeStyle: 'short'
            })}
          </Text>

          {logData && (
            <>
              <Hr style={hr} />
              <Heading as="h2" style={h2}>Log Details</Heading>
              <CodeBlock
                code={logData}
                language="json"
                theme={dracula}
                lineNumbers
                style={codeBlock}
              />
            </>
          )}

          {actionUrl && (
            <>
              <Hr style={hr} />
              <Link href={actionUrl} style={{ ...button, backgroundColor: severityColor }}>
                {actionLabel}
              </Link>
            </>
          )}

          <Hr style={hr} />
          <Text style={footer}>
            This is an automated notification. Please do not reply to this email.
          </Text>
        </Container>
      </Body>
    </Html>
  );
}

Notification.PreviewProps = {
  title: 'Deployment Failed',
  message: 'The deployment to production environment has failed. Please review the logs and take corrective action.',
  severity: 'error',
  timestamp: new Date(),
  logData: `{
  "error": "Build failed",
  "exit_code": 1,
  "duration": "2m 34s",
  "commit": "abc123def"
}`,
  actionUrl: 'https://example.com/deployments/123',
  actionLabel: 'View Deployment'
} as NotificationProps;

const main = { backgroundColor: '#f6f9fc', fontFamily: 'monospace, Arial, sans-serif' };
const container = { 
  margin: '0 auto', 
  padding: '0',
  maxWidth: '600px',
  backgroundColor: '#ffffff',
  border: '1px solid #e6ebf1',
  borderRadius: '4px',
  overflow: 'hidden'
};
const statusBar = { height: '4px', width: '100%' };
const h1 = { fontSize: '24px', fontWeight: 'bold', color: '#333', margin: '24px 24px 16px 24px' };
const h2 = { fontSize: '18px', fontWeight: 'bold', color: '#333', margin: '16px 24px' };
const badge = {
  display: 'inline-block',
  padding: '4px 12px',
  fontSize: '12px',
  fontWeight: 'bold',
  color: '#fff',
  borderRadius: '12px',
  marginLeft: '24px',
  marginBottom: '16px'
};
const text = { fontSize: '16px', lineHeight: '24px', color: '#333', margin: '0 24px 16px 24px' };
const timestamp = { fontSize: '14px', color: '#666', margin: '0 24px 24px 24px' };
const hr = { borderColor: '#e6ebf1', margin: '24px 0' };
const codeBlock = { margin: '0 24px' };
const button = {
  display: 'inline-block',
  padding: '12px 24px',
  fontSize: '16px',
  fontWeight: 'bold',
  color: '#fff',
  textDecoration: 'none',
  borderRadius: '4px',
  margin: '0 24px 24px 24px'
};
const footer = { fontSize: '12px', color: '#8898aa', margin: '0 24px 24px 24px' };

// Need to define Section for this example
const Section = ({ children, style }: { children?: React.ReactNode; style?: React.CSSProperties }) => (
  <div style={style}>{children}</div>
);
```

## Multi-Column Newsletter

```tsx
import { 
  Html, Head, Preview, Body, Container, Section, Row, Column, 
  Heading, Text, Img, Button, Hr, Link 
} from '@react-email/components';

interface Article {
  title: string;
  excerpt: string;
  image: string;
  url: string;
  author: string;
  date: string;
}

interface NewsletterProps {
  articles: Article[];
  unsubscribeUrl: string;
}

export default function Newsletter({ articles, unsubscribeUrl }: NewsletterProps) {
  return (
    <Html lang="en">
      <Head />
      <Preview>Your weekly roundup of the latest articles</Preview>
      <Body style={main}>
        <Container style={container}>
          {/* Header */}
          <Section style={header}>
            <Img 
              src="https://via.placeholder.com/150x50?text=Logo" 
              alt="Company Logo"
              width="150"
              height="50"
            />
          </Section>

          <Heading style={h1}>This Week's Highlights</Heading>
          <Text style={intro}>
            Here are the top articles from this week. Enjoy your reading!
          </Text>

          <Hr style={hr} />

          {/* Featured Article */}
          {articles[0] && (
            <Section style={featuredSection}>
              <Img 
                src={articles[0].image} 
                alt={articles[0].title}
                width="600"
                style={featuredImage}
              />
              <Heading as="h2" style={h2}>{articles[0].title}</Heading>
              <Text style={excerpt}>{articles[0].excerpt}</Text>
              <Text style={meta}>
                By {articles[0].author} • {articles[0].date}
              </Text>
              <Button href={articles[0].url} style={button}>
                Read More
              </Button>
            </Section>
          )}

          <Hr style={hr} />

          {/* Two-Column Articles */}
          {articles.slice(1, 5).length > 0 && (
            <>
              <Heading as="h2" style={h2}>More From This Week</Heading>
              {Array.from({ length: Math.ceil(articles.slice(1, 5).length / 2) }).map((_, rowIndex) => {
                const leftArticle = articles[1 + rowIndex * 2];
                const rightArticle = articles[2 + rowIndex * 2];
                
                return (
                  <Section key={rowIndex} style={articleRow}>
                    <Row>
                      {leftArticle && (
                        <Column style={articleColumn}>
                          <Img 
                            src={leftArticle.image} 
                            alt={leftArticle.title}
                            width="280"
                            style={articleImage}
                          />
                          <Heading as="h3" style={h3}>{leftArticle.title}</Heading>
                          <Text style={articleExcerpt}>{leftArticle.excerpt}</Text>
                          <Link href={leftArticle.url} style={link}>
                            Read article →
                          </Link>
                        </Column>
                      )}
                      
                      {rightArticle && (
                        <Column style={articleColumn}>
                          <Img 
                            src={rightArticle.image} 
                            alt={rightArticle.title}
                            width="280"
                            style={articleImage}
                          />
                          <Heading as="h3" style={h3}>{rightArticle.title}</Heading>
                          <Text style={articleExcerpt}>{rightArticle.excerpt}</Text>
                          <Link href={rightArticle.url} style={link}>
                            Read article →
                          </Link>
                        </Column>
                      )}
                    </Row>
                  </Section>
                );
              })}
            </>
          )}

          <Hr style={hr} />

          {/* Footer */}
          <Section style={footer}>
            <Text style={footerText}>
              You're receiving this because you subscribed to our newsletter.
            </Text>
            <Link href={unsubscribeUrl} style={unsubscribeLink}>
              Unsubscribe from this list
            </Link>
            <Text style={footerText}>
              © 2026 Company Name. All rights reserved.
            </Text>
          </Section>
        </Container>
      </Body>
    </Html>
  );
}

Newsletter.PreviewProps = {
  articles: [
    {
      title: 'The Future of Web Development in 2026',
      excerpt: 'Exploring the latest trends and technologies shaping modern web development.',
      image: 'https://via.placeholder.com/600x300',
      url: 'https://example.com/article-1',
      author: 'Jane Doe',
      date: 'Jan 15, 2026'
    },
    {
      title: 'React Server Components Explained',
      excerpt: 'A deep dive into React Server Components and their benefits.',
      image: 'https://via.placeholder.com/280x140',
      url: 'https://example.com/article-2',
      author: 'John Smith',
      date: 'Jan 14, 2026'
    },
    {
      title: 'Building Accessible Web Apps',
      excerpt: 'Best practices for creating inclusive digital experiences.',
      image: 'https://via.placeholder.com/280x140',
      url: 'https://example.com/article-3',
      author: 'Sarah Johnson',
      date: 'Jan 13, 2026'
    }
  ],
  unsubscribeUrl: 'https://example.com/unsubscribe'
} as NewsletterProps;

const main = { backgroundColor: '#ffffff', fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif' };
const container = { margin: '0 auto', maxWidth: '600px' };
const header = { padding: '40px 20px 20px 20px', textAlign: 'center' as const };
const h1 = { fontSize: '32px', fontWeight: 'bold', color: '#1a1a1a', margin: '0 20px 16px 20px', textAlign: 'center' as const };
const h2 = { fontSize: '24px', fontWeight: 'bold', color: '#1a1a1a', margin: '32px 20px 16px 20px' };
const h3 = { fontSize: '18px', fontWeight: 'bold', color: '#1a1a1a', margin: '12px 0 8px 0' };
const intro = { fontSize: '16px', lineHeight: '24px', color: '#666', margin: '0 20px 24px 20px', textAlign: 'center' as const };
const hr = { borderColor: '#e6ebf1', margin: '32px 20px' };
const featuredSection = { padding: '0 20px' };
const featuredImage = { width: '100%', borderRadius: '8px', marginBottom: '16px' };
const excerpt = { fontSize: '16px', lineHeight: '24px', color: '#666', margin: '16px 0' };
const meta = { fontSize: '14px', color: '#999', margin: '8px 0 16px 0' };
const button = {
  backgroundColor: '#007bff',
  color: '#fff',
  padding: '12px 24px',
  borderRadius: '4px',
  textDecoration: 'none',
  display: 'inline-block',
  fontWeight: 'bold'
};
const articleRow = { padding: '0 20px', marginBottom: '24px' };
const articleColumn = { width: '48%', verticalAlign: 'top' as const, padding: '0 1%' };
const articleImage = { width: '100%', borderRadius: '4px', marginBottom: '12px' };
const articleExcerpt = { fontSize: '14px', lineHeight: '20px', color: '#666', margin: '8px 0' };
const link = { fontSize: '14px', color: '#007bff', textDecoration: 'none', fontWeight: '600' };
const footer = { backgroundColor: '#f8f9fa', padding: '32px 20px', marginTop: '32px', textAlign: 'center' as const };
const footerText = { fontSize: '14px', color: '#666', margin: '8px 0' };
const unsubscribeLink = { fontSize: '14px', color: '#007bff', textDecoration: 'underline', margin: '8px 0', display: 'block' };
```

## Team Invitation Email

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

interface TeamInvitationProps {
  inviterName: string;
  inviterEmail: string;
  teamName: string;
  role: string;
  inviteUrl: string;
  expiryDays: number;
}

export default function TeamInvitation({
  inviterName,
  inviterEmail,
  teamName,
  role,
  inviteUrl,
  expiryDays
}: TeamInvitationProps) {
  return (
    <Html lang="en">
      <Head />
      <Preview>You've been invited to join {teamName}</Preview>
      <Body style={main}>
        <Container style={container}>
          <Heading style={h1}>You're Invited!</Heading>
          
          <Text style={text}>
            <strong>{inviterName}</strong> ({inviterEmail}) has invited you to join the{' '}
            <strong>{teamName}</strong> team.
          </Text>

          <Section style={infoBox}>
            <Text style={infoLabel}>Role</Text>
            <Text style={infoValue}>{role}</Text>
          </Section>

          <Text style={text}>
            Click the button below to accept the invitation and get started.
          </Text>

          <Button href={inviteUrl} style={button}>
            Accept Invitation
          </Button>

          <Hr style={hr} />

          <Text style={footer}>
            This invitation will expire in {expiryDays} day{expiryDays > 1 ? 's' : ''}.
          </Text>
          <Text style={footer}>
            If you weren't expecting this invitation, you can safely ignore this email.
          </Text>
        </Container>
      </Body>
    </Html>
  );
}

TeamInvitation.PreviewProps = {
  inviterName: 'John Doe',
  inviterEmail: '[email protected]',
  teamName: 'Acme Corp Engineering',
  role: 'Developer',
  inviteUrl: 'https://example.com/invite/abc123',
  expiryDays: 7
} as TeamInvitationProps;

const main = { backgroundColor: '#f6f9fc', fontFamily: 'Arial, sans-serif' };
const container = { margin: '0 auto', padding: '40px 20px', maxWidth: '560px', backgroundColor: '#ffffff' };
const h1 = { fontSize: '28px', fontWeight: 'bold', color: '#333', textAlign: 'center' as const, marginBottom: '24px' };
const text = { fontSize: '16px', lineHeight: '26px', color: '#333', margin: '16px 0' };
const infoBox = { 
  backgroundColor: '#f8f9fa', 
  padding: '20px', 
  borderRadius: '4px', 
  border: '1px solid #e6ebf1',
  margin: '24px 0'
};
const infoLabel = { 
  fontSize: '12px', 
  color: '#666', 
  textTransform: 'uppercase' as const,
  fontWeight: 'bold',
  marginBottom: '8px'
};
const infoValue = { fontSize: '18px', color: '#333', fontWeight: 'bold', margin: '0' };
const button = {
  backgroundColor: '#28a745',
  color: '#fff',
  padding: '14px 28px',
  borderRadius: '4px',
  textDecoration: 'none',
  textAlign: 'center' as const,
  display: 'block',
  fontWeight: 'bold',
  fontSize: '16px',
  margin: '24px 0'
};
const hr = { borderColor: '#e6ebf1', margin: '24px 0' };
const footer = { fontSize: '14px', color: '#8898aa', lineHeight: '20px', margin: '8px 0' };

// Define Section for this example
const Section = ({ children, style }: { children?: React.ReactNode; style?: React.CSSProperties }) => (
  <div style={style}>{children}</div>
);
```

These patterns demonstrate:
- Proper component usage
- TypeScript typing
- Inline styling
- Preview props for testing
- Responsive layouts
- Common email scenarios

```

react-email | SkillHub