Learn how to set up and use email with Resend or Cloudflare Email Service and React Email templates
ShipTanStarter supports Resend and Cloudflare Email Service as email providers, using React Email for building email templates.
Setup
ShipTanStarter supports Resend and Cloudflare Email Service as built-in providers.
Cloudflare Email
Enable Cloudflare Email Service
Enable the Email Service in your Cloudflare Dashboard:
- Go to Cloudflare Dashboard > Build > Compute > Email Service > Email Sending
- Click Onboard Domain in the upper right corner, add and verify your sending domain (e.g.,
example.com)
You can find more details in the Cloudflare Email Service documentation.
Configure Cloudflare API Token
Follow the Cloudflare guide to ensure your API Token has the Account > Email Sending > Edit permission.
Update Website Configuration
Update website.ts to use Cloudflare as the mail provider:
Note that fromEmail is the email address used to send emails, and supportEmail is the email address used to receive emails (e.g., contact form submissions). The email domain must match the domain you verified in Cloudflare Email Service.
export const websiteConfig = {
// ...other config
mail: {
enable: true, // Whether to enable email functionality
provider: 'cloudflare', // Mail provider to use
fromEmail: 'YourApp <[email protected]>', // Sender email address
supportEmail: 'YourApp <[email protected]>', // Support email address
},
// ...other config
}Resend
Create Resend Account
Create a Resend account at resend.com, bind and verify your domain.
Get API Key
Go to Resend Dashboard > API Keys, and create a new API key with the appropriate permissions for sending emails.
Configure Environment Variables
Add the following to your .env file:
RESEND_API_KEY=re_xxxxxxxxxxxxUpdate Website Configuration
Update website.ts to use Resend as the mail provider:
export const websiteConfig = {
// ...other config
mail: {
enable: true, // Whether to enable email functionality
provider: 'resend', // Mail provider to use
fromEmail: 'YourApp <[email protected]>', // Sender email address
supportEmail: 'YourApp <[email protected]>', // Support email address
},
// ...other config
}If you are setting up your environment, you can now go back to the Environment Configuration and continue. The rest of this document can be read later.
Customization
Create New Email Templates
- Create an email template in the
src/mail/templatesdirectory:
import { EmailLayout } from '../components/email-layout';
import { EmailButton } from '../components/email-button';
interface MyCustomEmailProps {
username: string;
actionUrl: string;
}
export function MyCustomEmail({
username,
actionUrl,
}: MyCustomEmailProps) {
return (
<EmailLayout>
<p>Hello {username}!</p>
<p>Thanks for joining our platform. Click the button below to get started.</p>
<EmailButton href={actionUrl}>Get Started</EmailButton>
</EmailLayout>
);
}- Add the template name to the
EmailTemplatetype insrc/mail/types.ts:
export type EmailTemplate =
| 'forgotPassword'
| 'verifyEmail'
| 'subscribeNewsletter'
| 'contactMessage'
| 'myCustomEmail'; // ← add your template name- Register the component in
src/mail/render.ts:
import MyCustomEmail from './templates/my-custom-email';
const EmailTemplates = {
forgotPassword: ForgotPassword,
verifyEmail: VerifyEmail,
subscribeNewsletter: SubscribeNewsletter,
contactMessage: ContactMessage,
myCustomEmail: MyCustomEmail, // ← register here
} as const;- Add a subject line in your messages file (
src/messages/en.ts):
mail: {
// ...existing templates
myCustomEmail: {
subject: 'Welcome to Our Platform',
},
}- Preview your template locally:
pnpm email:dev- Use the template in your code:
await sendEmail({
to: '[email protected]',
template: 'myCustomEmail',
context: {
username: 'John',
actionUrl: 'https://example.com/start',
},
});Create a New Mail Provider
ShipTanStarter supports extending with new mail providers:
- Create a new file in the
src/mail/providerdirectory (e.g.,sendgrid.ts) - Implement the
MailProviderinterface defined insrc/mail/types.ts, which requires the following methods:
import type {
MailProvider,
SendEmailResult,
SendRawEmailParams,
SendTemplateParams,
} from '../types';
export class SendGridProvider implements MailProvider {
getProviderName(): string {
return 'sendgrid';
}
async sendTemplate(params: SendTemplateParams): Promise<SendEmailResult> {
// Logic for sending emails using templates
}
async sendRawEmail(params: SendRawEmailParams): Promise<SendEmailResult> {
// Logic for sending raw HTML emails
}
}- Register the new provider in the
providerRegistryinsrc/mail/index.ts:
import { SendGridProvider } from './provider/sendgrid';
const providerRegistry: Record<MailProviderName, ProviderFactory> = {
resend: () => new ResendProvider(),
cloudflare: () => new CloudflareProvider(),
sendgrid: () => new SendGridProvider(),
};Next Steps
Now that you understand how to use email in ShipTanStarter, you might want to explore these related features: