# Templates as Code

Source: https://wraps.dev/docs/guides/templates

Write email templates as React components using React Email, preview them with hot-reload, and push to both SES and the Wraps dashboard.

## Getting Started

Initialize a templates directory in your project with the scaffold command:

terminal.sh

```
wraps email templates init
```

This creates the following structure:

Project Structure

```
wraps/├── wraps.config.ts          # Project configuration├── templates/│   └── welcome.tsx          # Example template├── brand.ts                 # Brand kit (colors, fonts, logo)└── _components/             # Shared components
```

templates/

Each file is a React component that renders to an email. Exported metadata like `subject` and `emailType` are used by the platform.

brand.ts

A shared brand kit for colors, fonts, and logos. Import it in your templates to keep a consistent look across all emails.

## Configuration

The `wraps.config.ts` file defines your project settings, including default sender addresses, template directories, and preview server options.

wraps.config.ts

```
import { defineConfig } from '@wraps.dev/client';export default defineConfig({  org: 'your-org-slug',  from: 'hello@yourdomain.com',  replyTo: 'support@yourdomain.com',  region: 'us-east-1',  templatesDir: './templates',  workflowsDir: './workflows',  brandFile: './brand.ts',  preview: {    port: 3333,  },});
```

## Writing Templates

Templates are standard React components built with [React Email](https://react.email) components. Each template file exports the component as default, along with metadata exports for the subject line, email type, and preview text.

wraps/templates/welcome.tsx

```
// wraps/templates/welcome.tsximport { Html, Head, Body, Container, Text, Button } from '@react-email/components';import { brand } from '../brand';export const subject = 'Welcome, {{name}}!';export const emailType = 'transactional';export const previewText = 'Thanks for signing up';export default function WelcomeEmail(props: {  name: string;  dashboardUrl: string;}) {  return (    <Html>      <Head />      <Body style={{ fontFamily: brand.fonts.body }}>        <Container>          <Text>Hi {props.name},</Text>          <Text>Welcome to our platform!</Text>          <Button            href={props.dashboardUrl}            style={{ backgroundColor: brand.colors.primary }}          >            Go to Dashboard          </Button>        </Container>      </Body>    </Html>  );}
```

### Template exports:

| Export | Type | Description |
| --- | --- | --- |
| `default` | React Component | The email template component (required) |
| `subject` | string | Subject line with {{variable}} interpolation |
| `emailType` | string | "transactional" or "marketing" |
| `previewText` | string | Preview text shown in email clients (optional) |

## Preview

Start the local preview server to see your templates rendered in the browser with hot-reload. Changes to your template files are reflected instantly.

terminal.sh

```
wraps email templates preview# Opens http://localhost:3333 with hot-reload
```

Hot-reload enabled

The preview server watches for file changes and automatically reloads. You can also switch between templates and test different prop values in the preview UI.

## Push to SES + Dashboard

Push your templates to both AWS SES (as SES templates) and the Wraps dashboard (for visual editing and analytics). Only modified templates are pushed by default.

terminal.sh

```
# Push all changed templateswraps email templates push# Push specific templatewraps email templates push --template welcome# Force push (overwrite dashboard changes)wraps email templates push --force# Dry run (see what would change)wraps email templates push --dry-run
```

### Change Detection

Wraps uses a lockfile (`wraps/.wraps-lock.json`) to track which templates have been pushed and their content hashes. Only modified templates are pushed on subsequent runs. Use `--force` to re-push all templates regardless of changes.

## Sending with Templates

Once a template is pushed, you can send emails using the template name and pass in dynamic data through the SDK:

send.ts

```
import { WrapsEmail } from '@wraps.dev/email';const email = new WrapsEmail();await email.sendTemplate({  from: 'hello@yourdomain.com',  to: 'user@example.com',  template: 'welcome',  templateData: {    name: 'Alice',    dashboardUrl: 'https://app.example.com',  },});
```

The template data is merged with the template at send time. Variable placeholders in the subject line (like `{{name}}`) are also replaced.

## Next Steps

Building Workflows

Create automated email sequences using the Wraps workflow DSL.

[Workflow Guide](https://wraps.dev/docs/guides/workflows)

Sharing Templates With Marketing

What happens when somebody edits a template in the dashboard after you pushed it, and how to split copy from structure.

[Handoff Guide](https://wraps.dev/docs/guides/template-handoff)

Email SDK

Full SDK reference for sending emails programmatically.

[SDK Reference](https://wraps.dev/docs/sdk-reference)
