Learn how to set up and use email with Cloudflare Email Service and React Email templates
ShipTanStarter uses Cloudflare Email Service as the email provider, using React Email for building email templates.
Setup
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
}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'
| '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,
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> = {
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: