Emails

Email service integration with multiple providers

Installation

1

Install the Package

Add Emails to your project using the Codelesskit CLI:

pnpm dlx codelesskit@latest add emails
2

Set Environment Variables

Create a `.env` file in the root of your project and add the following environment variables. For detailed setup instructions, see how to create an email client.

.env
1
2
3
4
5
6
7
8
# Email Configuration
EMAIL_FROM="noreply@example.com"
EMAIL_REPLY_TO="support@example.com"
NEXT_PUBLIC_APP_URL="http://localhost:3000"
 
# Resend Configuration
RESEND_API_KEY="your_resend_api_key_here"
# Get your API key from: https://resend.com/api-keys

File Tree

The following files are installed when you add Emails:

File Structure
1
2
3
4
5
6
7
8
9
10
├─ lib/
│ └─ emails/
│ ├─ actions.ts
│ ├─ config.ts
│ ├─ index.ts
│ ├─ templates.tsx
│ └─ types.ts
└─ components/
└─ emails/
└─ email-form.tsx

Usage

Once you've installed Emails, you can start using the following actions:

Send Email

Send emails using the sendEmail function. You can send plain HTML emails without templates:

lib/emails/example.ts
1
2
3
4
5
6
7
8
import { sendEmail } from '@/lib/emails/actions'
 
await sendEmail({
to: 'user@example.com',
subject: 'Welcome!',
html: '<h1>Welcome to our app</h1><p>Thank you for signing up!</p>',
text: 'Welcome to our app. Thank you for signing up!'
})

Send Email with Template

The best practice is to create template functions that use baseEmailWrapper. Here's a real-world example from the auth configuration showing how to send a verification email:

lib/auth/config.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { renderVerifyEmail } from '@/lib/auth/templates'
import { sendEmail } from '@/lib/emails/actions'
 
// In your auth configuration or API route
const html = renderVerifyEmail({
verifyLink: url,
})
 
await sendEmail({
html,
to: user.email,
subject: 'Verify your email address',
text: `Click the link to verify your email: ${url}`,
})

Create an Email Template

Create reusable email template functions that use baseEmailWrapper. Here's an example of a verification email template from the auth feature to show how it works:

Preview
Your App Name Logo

Welcome to Your App Name!

Thank you for signing up. Please click the button below to verify your email address and activate your account.

Verify Email

If you did not create this account, you can safely ignore this email.

© 2024 Your App Name. All rights reserved.
lib/auth/templates.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { baseEmailWrapper } from '@/lib/emails/templates'
import { APP_NAME } from '@/lib/constants'
 
const primaryColor = '#000000'
 
export function renderVerifyEmail({
verifyLink,
}: {
verifyLink: string
}): string {
const content = `
<h2 style="margin: 0; font-size: 18px; font-weight: 500; color: #000;">Welcome to ${APP_NAME}!</h2>
<p style="font-size: 14px; color: #a1a1aa">
Thank you for signing up. Please click the button below to verify your email address and activate your account.
</p>
<a
href="${verifyLink}"
style="
display: inline-block;
margin: 24px 0;
padding: 8px 24px;
background: ${primaryColor};
color: #fff;
border-radius: 6px;
text-decoration: none;
font-weight: 500;
font-size: 14px;">
Verify Email
</a>
<p style="font-size: 12px; color: #a1a1aa; margin-top: 24px;">
If you did not create this account, you can safely ignore this email.
</p>
`
return baseEmailWrapper(content)
}

Customize the Base Email Wrapper

The baseEmailWrapper function wraps your content with a branded layout. You can fully customize this wrapper or use emails without it, but it's recommended for a professional and consistent look. Customize it by updating APP_NAME in lib/constants.ts, changing the logoUrl, and modifying the styles. The wrapper includes a logo header, your content area, and a footer with copyright.

lib/emails/templates.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// lib/emails/templates.tsx
import { APP_NAME } from '@/lib/constants'
 
export function baseEmailWrapper(content: string): string {
// Update this URL to your logo (e.g., from public folder)
const logoUrl = 'https://www.codelesskit.com/logo-dark.png'
return `
<div style="font-family: Inter, Arial, sans-serif; background: #ffffff; padding: 32px;">
<div style="max-width: 480px; margin: 0 auto; background: #fff; border-radius: 12px; border: 1px solid #00000033; box-shadow: 0 2px 2px rgba(0,0,0,0.04); overflow: hidden;">
<div style="padding: 24px 32px; font-weight: 500; font-size: 20px;">
<img src="${logoUrl}" alt="${APP_NAME} Logo" width="40" height="40" style="border-radius: 8px; overflow:hidden;" >
</div>
<div style="padding: 0 32px;">
${content}
</div>
<div style="padding: 24px 32px; font-size: 12px; color: #a1a1aa">
&copy; ${new Date().getFullYear()} ${APP_NAME}. All rights reserved.
</div>
</div>
</div>
`
}

References

For more information about Emails, check out these resources:

Resend Documentation
Complete documentation for Resend, including API reference, templates, and best practices.
SendGrid Documentation
Comprehensive guides and API reference for SendGrid email service.
Postmark Documentation
Documentation for Postmark transactional email service with API reference and guides.
Emails | Codelesskit