A powerful email template builder for Svelte applications, inspired by React Email.
pnpm add mail-svelte
# or
npm install mail-svelte
# or
yarn add mail-svelte
Here's a basic example of how to create an email template:
<script lang="ts">
import { Html, Head, Body, Container, Section, Text } from 'mail-svelte';
</script>
<Html>
<Head>
<title>Welcome Email</title>
</Head>
<Body>
<Container>
<Section>
<Text>Hello from Svelte Mail!</Text>
</Section>
</Container>
</Body>
</Html>
The root component for your email template.
<Html lang="en" dir="ltr">
<!-- Your email content -->
</Html>
Props:
lang
: Language code (default: "en")dir
: Text direction (default: "ltr")Contains metadata and styles for your email.
<script lang="ts">
import { Head, Font } from 'mail-svelte';
</script>
<Head>
<title>Email Title</title>
<Font fontFamily="Arial" fallbackFontFamily={['Helvetica', 'sans-serif']} />
</Head>
The Head component automatically includes:
Add custom fonts to your email. Can be used in two ways:
Web Font:
<script lang="ts">
import { Font } from 'mail-svelte';
</script>
<Font
fontFamily="Roboto"
fallbackFontFamily={['Helvetica', 'sans-serif']}
webFont={{
url: 'https://fonts.googleapis.com/css2?family=Roboto',
format: 'woff2'
}}
/>
System Font:
<script lang="ts">
import { Font } from 'mail-svelte';
</script>
<Font fontFamily="Arial" fallbackFontFamily="sans-serif" />
Props:
fontFamily
: Primary font name (required)fallbackFontFamily
: String or array of fallback fonts (optional, defaults to 'sans-serif')webFont
: Optional web font configuration object ({ url: string, format: string }
). If provided, an @font-face
rule will be generated.fontStyle
: Font style (optional, default: 'normal')fontWeight
: Font weight (optional, default: 400)Container for your email content.
<script lang="ts">
import { Body } from 'mail-svelte';
</script>
<Body style="background-color: #f6f9fc;">
<!-- Email content -->
</Body>
A centered wrapper with a maximum width.
<script lang="ts">
import { Container } from 'mail-svelte';
</script>
<Container style="max-width: 600px;">
<!-- Contained content -->
</Container>
A structural component for grouping content.
<script lang="ts">
import { Section } from 'mail-svelte';
</script>
<Section style="padding: 20px 0;">
<!-- Section content -->
</Section>
Create responsive layouts.
<script lang="ts">
import { Row, Column, Text } from 'mail-svelte';
</script>
<Row>
<Column style="padding: 10px;">
<Text>Column 1</Text>
</Column>
<Column style="padding: 10px;">
<Text>Column 2</Text>
</Column>
</Row>
Create email-client compatible buttons.
<script lang="ts">
import { Button } from 'mail-svelte';
</script>
<Button href="https://example.com" style="background-color: #000; color: #fff;" padding="12px 20px">
Click me
</Button>
padding
: Shorthand for all sides. Accepts CSS units: px
, em
, rem
, %
, or number (pixels).paddingTop
, paddingRight
, paddingBottom
, paddingLeft
: Individual paddings. Accepts same units as above. These override the corresponding value from padding
if both are provided.Examples:
<!-- Shorthand padding (all sides) -->
<Button padding="16px">All sides 16px</Button>
<!-- Vertical | Horizontal -->
<Button padding="10px 24px">10px top/bottom, 24px left/right</Button>
<!-- Top | Horizontal | Bottom -->
<Button padding="8px 20px 12px">8px top, 20px left/right, 12px bottom</Button>
<!-- Top | Right | Bottom | Left -->
<Button padding="8px 16px 12px 24px">8px top, 16px right, 12px bottom, 24px left</Button>
<!-- Mixed units -->
<Button padding="1em 10%">1em top/bottom, 10% left/right</Button>
<!-- Individual overrides -->
<Button padding="12px" paddingLeft="32px">12px all, but 32px left</Button>
<!-- All individual -->
<Button paddingTop="10px" paddingRight="20px" paddingBottom="10px" paddingLeft="20px">
Explicit sides
</Button>
mso-font-width
.em
, rem
, and %
(relative to 600px width).href
: Button link URL (required)target
: Link target (default: "_blank")style
: Inline styles (string or object)class
: CSS class<a>
) attributes<Button
href="https://example.com"
style="background: #0070f3; color: #fff; border-radius: 6px;"
padding="1em 2em"
paddingLeft="40px"
target="_self"
class="my-button"
aria-label="Special Button"
>
Advanced Button
</Button>
Renders text content with sensible defaults.
<script lang="ts">
import { Text } from 'mail-svelte';
</script>
<Text style="color: #333; font-size: 16px;" as="span">Your text content</Text>
Props:
as
: HTML element to render (default: "p")style
: Inline styles (string).as
.Default styles (merged with the provided style
prop):
font-size: 14px
line-height: 24px
margin: 16px 0
Create styled links.
<script lang="ts">
import { Link } from 'mail-svelte';
</script>
<Link href="https://example.com" style="color: #067df7;">Click here</Link>
Props:
href
: Required URLtarget
: Link target (default: "_blank")Img
)Add images with proper email client support.
<script lang="ts">
import { Img } from 'mail-svelte';
</script>
<Img
src="https://example.com/image.jpg"
alt="Description"
width="600"
height="400"
style="border-radius: 4px;"
/>
Props:
src
: Image URLalt
: Alt textwidth
: Image widthheight
: Image heightNote on Centering: Because the Img
component defaults to display: block;
, using text-align: center;
on a parent element (like <Column>
) will not center the image. To center an image, apply margin: 0 auto;
directly to the Img
component's style
prop:
<Img src="..." alt="..." width="100" style="margin: 0 auto;" />
Note on Right Alignment: If you want to right-align a block-level element (such as a button or a link with display: block
) inside a Column
, setting text-align: right;
on the parent will not work. Instead, add margin-left: auto; margin-right: 0;
to the element's style
prop:
<script lang="ts">
import { Link } from 'mail-svelte';
</script>
<Link href="#" style="display: block; width: 220px; margin-left: auto; margin-right: 0;">
Track Package
</Link>
Add horizontal rules.
<script lang="ts">
import { Hr } from 'mail-svelte';
</script>
<Hr style="border-color: #e6e6e6;" />
Default styles:
Create headings with proper styling.
<script lang="ts">
import { Heading } from 'mail-svelte';
</script>
<Heading as="h1" style="font-size: 24px;" m="0" mb="20px">Your Heading</Heading>
Props:
as
: Heading level (h1-h6)m
, mx
, my
, mt
, mr
, mb
, ml
Adds preview text (preheader) to your email, which appears in the inbox list view of most email clients.
<script lang="ts">
import { Preview } from 'mail-svelte';
</script>
<Preview text="This text appears in the inbox preview, but not the email body." />
Props:
text
: The preview text string (required).style
: Optional inline styles (string or object) for the hidden div
element.Details:
text
inside a hidden div
.PREVIEW_MAX_LENGTH
).
, ‌
, etc.) to fill the remaining space up to the 150-character limit.Here's a complete example of a welcome email:
<script lang="ts">
import {
Html,
Head,
Font,
Preview,
Body,
Container,
Section,
Row,
Column,
Heading,
Text,
Button,
Img,
Hr,
Link
} from 'mail-svelte';
</script>
<Html>
<Head>
<title>Welcome to Our Service</title>
<Font
fontFamily="Roboto"
fallbackFontFamily={['Helvetica', 'Arial', 'sans-serif']}
webFont={{
url: 'https://fonts.googleapis.com/css2?family=Roboto',
format: 'woff2'
}}
/>
</Head>
<Preview>Welcome to our platform! We're excited to have you on board.</Preview>
<Body style="background-color: #f6f9fc; font-family: 'Roboto', Helvetica, Arial, sans-serif;">
<Container style="max-width: 600px; margin: 0 auto; padding: 20px 0;">
<Section style="background-color: #ffffff; padding: 40px; border-radius: 4px;">
<Img
src="https://example.com/logo.png"
alt="Company Logo"
width="150"
height="50"
style="margin-bottom: 30px;"
/>
<Heading as="h1" style="color: #1a1a1a; font-size: 24px;" mb="20px">
Welcome aboard!
</Heading>
<Text style="color: #4a4a4a; font-size: 16px; line-height: 1.5;" mb="20px">
We're thrilled to have you as a new member of our community.
</Text>
<Button
href="https://example.com/get-started"
style="background-color: #0070f3; color: #ffffff; border-radius: 4px;"
padding="12px 32px"
>
Get Started
</Button>
<Hr style="margin: 30px 0;" />
<Row>
<Column style="padding: 10px;">
<Text style="color: #666666; font-size: 14px;">
Need help? <Link href="https://example.com/support">Contact Support</Link>
</Text>
</Column>
</Row>
</Section>
</Container>
</Body>
</Html>
The components are built with email client compatibility in mind and include specific optimizations for:
The components automatically handle: