better-svelte-email 0.3.1 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Anatole Dufour
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,37 +1,58 @@
1
- # better-svelte-email
2
-
3
- [![Tests](https://github.com/Konixy/better-svelte-email/actions/workflows/release.yml/badge.svg)](https://github.com/Konixy/better-svelte-email/actions/workflows/release.yml)
4
- [![npm version](https://img.shields.io/npm/v/better-svelte-email.svg?logo=npm)](https://www.npmjs.com/package/better-svelte-email)
5
- [![GitHub stars](https://img.shields.io/github/stars/Konixy/better-svelte-email?style=default&logo=github)](https://github.com/Konixy/better-svelte-email/stargazers)
6
-
7
- A Svelte preprocessor that transforms Tailwind CSS classes in email components to inline styles with responsive media query support.
1
+ <p align="center">
2
+ <h3 align="center">Better Svelte Email</h3>
3
+ <p align="center">
4
+ Create beautiful emails in Svelte with first-class Tailwind support
5
+ </p>
6
+ <p align="center">
7
+ <a href="https://better-svelte-email.konixy.fr">Website</a>
8
+ ·
9
+ <a href="https://github.com/Konixy/better-svelte-email">GitHub</a>
10
+ </p>
11
+ <p align="center">
12
+ <a href="https://github.com/Konixy/better-svelte-email/actions/workflows/release.yml">
13
+ <img src="https://github.com/Konixy/better-svelte-email/actions/workflows/release.yml/badge.svg" alt="Tests">
14
+ </a>
15
+ <a href="https://www.npmjs.com/package/better-svelte-email">
16
+ <img src="https://img.shields.io/npm/v/better-svelte-email.svg?logo=npm" alt="npm version">
17
+ </a>
18
+ <a href="https://github.com/Konixy/better-svelte-email/stargazers">
19
+ <img src="https://img.shields.io/github/stars/Konixy/better-svelte-email?style=default&logo=github" alt="GitHub stars">
20
+ </a>
21
+ </p>
22
+ </p>
8
23
 
9
24
  ## Features
10
25
 
11
- **Stable & Future-Proof** - Uses Svelte's public preprocessor API
12
- 🎨 **Tailwind CSS Support** - Transforms Tailwind classes to inline styles for email clients
13
- 📱 **Responsive Emails** - Preserves responsive classes (`sm:`, `md:`, `lg:`) as media queries
14
- **Build-Time Transformation** - Zero runtime overhead
15
- 🔍 **TypeScript First** - Fully typed with comprehensive type definitions
16
- ✅ **Well Tested** - Extensive test coverage with unit and integration tests
26
+ - **Stable & Future-Proof** - Uses Svelte's public preprocessor API
27
+ - **Tailwind CSS Support** - Transforms Tailwind classes to inline styles for email clients
28
+ - **Built-in Email Preview** - Visual email preview and test sending
29
+ - **TypeScript First** - Fully typed with comprehensive type definitions
30
+ - **Well Tested** - Extensive test coverage with unit and integration tests
31
+
32
+ _See [Roadmap](./ROADMAP.md) for future features and planned improvements._
17
33
 
18
34
  ## Why?
19
35
 
20
- Email clients don't support modern CSS in `<style>` tags, requiring inline styles. But writing inline styles is tedious and hard to maintain. This preprocessor lets you write Tailwind CSS classes and automatically transforms them to inline styles at build time.
36
+ Existing Svelte email solutions have significant limitations:
37
+
38
+ - **svelte-email** hasn't been updated in over 2 years
39
+ - **svelte-email-tailwind** suffers from stability issues and maintaining it is not sustainable anymore
40
+
41
+ Better Svelte Email is a complete rewrite built on Svelte's official preprocessor API, providing the rock-solid foundation your email infrastructure needs. It brings the simplicity, reliability, and feature richness of [React Email](https://react.email/) to the Svelte ecosystem.
42
+
43
+ ## Quick Start
21
44
 
22
- ## Installation
45
+ ### 1. Install the package
23
46
 
24
47
  ```bash
25
- npm install better-svelte-email
48
+ npm i -D better-svelte-email
26
49
  # or
27
- bun add better-svelte-email
50
+ bun add -D better-svelte-email
28
51
  # or
29
- pnpm add better-svelte-email
52
+ pnpm add -D better-svelte-email
30
53
  ```
31
54
 
32
- ## Quick Start
33
-
34
- ### 1. Configure the Preprocessor
55
+ ### 2. Configure the Preprocessor
35
56
 
36
57
  Add the preprocessor to your `svelte.config.js`:
37
58
 
@@ -41,13 +62,7 @@ import { betterSvelteEmailPreprocessor } from 'better-svelte-email';
41
62
 
42
63
  /** @type {import('@sveltejs/kit').Config} */
43
64
  const config = {
44
- preprocess: [
45
- vitePreprocess(),
46
- betterSvelteEmailPreprocessor({
47
- pathToEmailFolder: '/src/lib/emails',
48
- debug: false
49
- })
50
- ],
65
+ preprocess: [vitePreprocess(), betterSvelteEmailPreprocessor()],
51
66
  kit: {
52
67
  adapter: adapter()
53
68
  }
@@ -56,19 +71,22 @@ const config = {
56
71
  export default config;
57
72
  ```
58
73
 
59
- ### 2. Create Email Components
74
+ ### 3. Create Email Components
60
75
 
61
76
  Create your email templates in `src/lib/emails/`:
62
77
 
63
78
  ```svelte
64
79
  <!-- src/lib/emails/welcome.svelte -->
65
80
  <script>
81
+ import { Html, Head, Body, Preview, Container, Text, Button } from 'better-svelte-email';
82
+
66
83
  let { name = 'User' } = $props();
67
84
  </script>
68
85
 
69
86
  <Html>
70
87
  <Head />
71
88
  <Body class="bg-gray-100">
89
+ <Preview preview="Welcome Email" />
72
90
  <Container class="mx-auto p-8">
73
91
  <Text class="mb-4 text-2xl font-bold">
74
92
  Welcome, {name}!
@@ -76,7 +94,7 @@ Create your email templates in `src/lib/emails/`:
76
94
 
77
95
  <Button
78
96
  href="https://example.com"
79
- class="rounded bg-blue-600 px-6 py-3 text-white sm:bg-green-600"
97
+ class="rounded bg-orange-600 px-6 py-3 text-white sm:text-sm"
80
98
  >
81
99
  Get Started
82
100
  </Button>
@@ -85,7 +103,7 @@ Create your email templates in `src/lib/emails/`:
85
103
  </Html>
86
104
  ```
87
105
 
88
- ### 3. Render and Send
106
+ ### 4. Render and Send
89
107
 
90
108
  ```typescript
91
109
  // src/routes/api/send-email/+server.ts
@@ -110,89 +128,90 @@ export async function POST({ request }) {
110
128
  }
111
129
  ```
112
130
 
113
- ## How It Works
131
+ ## Email Preview Component
132
+
133
+ Better Svelte Email includes a built-in preview component for visually developing and testing your email templates during development.
114
134
 
115
- The preprocessor transforms your Tailwind classes in three steps:
135
+ ### Setup
116
136
 
117
- ### 1. Non-Responsive Classes Inline Styles
137
+ Create a preview route in your SvelteKit app:
118
138
 
119
139
  ```svelte
120
- <!-- Input -->
121
- <Button class="bg-blue-500 p-4 text-white">Click</Button>
122
-
123
- <!-- Output -->
124
- <Button
125
- styleString="background-color: rgb(59, 130, 246); color: rgb(255, 255, 255); padding: 16px;"
126
- >
127
- Click
128
- </Button>
140
+ <!-- src/routes/preview/+page.svelte -->
141
+ <script lang="ts">
142
+ import { EmailPreview } from 'better-svelte-email/preview';
143
+
144
+ let { data } = $props();
145
+ </script>
146
+
147
+ <EmailPreview emailList={data.emails} />
129
148
  ```
130
149
 
131
- ### 2. Responsive Classes → Media Queries
150
+ ```typescript
151
+ // src/routes/preview/+page.server.ts
152
+ import { emailList, createEmail, sendEmail } from 'better-svelte-email/preview';
153
+ import { env } from '$env/dynamic/private';
132
154
 
133
- ```svelte
134
- <!-- Input -->
135
- <Button class="bg-blue-500 sm:bg-red-500">Click</Button>
155
+ export function load() {
156
+ const emails = emailList({
157
+ path: '/src/lib/emails' // optional, defaults to '/src/lib/emails'
158
+ });
136
159
 
137
- <!-- Output -->
138
- <Button class="sm_bg-red-500" styleString="background-color: rgb(59, 130, 246);">Click</Button>
160
+ return { emails };
161
+ }
139
162
 
140
- <!-- Injected into <Head> -->
141
- <style>
142
- @media (max-width: 475px) {
143
- .sm_bg-red-500 {
144
- background-color: rgb(239, 68, 68) !important;
145
- }
146
- }
147
- </style>
163
+ export const actions = {
164
+ ...createEmail,
165
+ ...sendEmail({ resendApiKey: env.RESEND_API_KEY })
166
+ };
148
167
  ```
149
168
 
150
- ### 3. Mixed Classes → Both
169
+ ### Features
151
170
 
152
- ```svelte
153
- <!-- Input -->
154
- <Button class="rounded bg-blue-500 p-4 sm:bg-red-500 md:p-6">Click</Button>
155
-
156
- <!-- Output -->
157
- <Button
158
- class="sm_bg-red-500 md_p-6"
159
- styleString="border-radius: 4px; background-color: rgb(59, 130, 246); padding: 16px;"
160
- >
161
- Click
162
- </Button>
171
+ - **HTML Source View** - Inspect the generated HTML with syntax highlighting
172
+ - **Copy to Clipboard** - Quickly copy the rendered HTML
173
+ - **Test Email Sending** - Send test emails directly from the preview UI using Resend
174
+ - **Template List** - Browse all your email templates in one place
175
+
176
+ ### Environment Variables
177
+
178
+ To enable test email sending, add your Resend API key to your `.env` file:
179
+
180
+ ```env
181
+ RESEND_API_KEY=re_your_api_key_here
163
182
  ```
164
183
 
165
- ## Configuration
184
+ Get your API key from [Resend](https://resend.com/).
185
+
186
+ ### Custom Email Provider
166
187
 
167
- ### Options
188
+ If you prefer to use a different email provider, you can pass a custom send function:
168
189
 
169
190
  ```typescript
170
- interface PreprocessorOptions {
171
- /**
172
- * Path to folder containing email components
173
- * @default '/src/lib/emails'
174
- */
175
- pathToEmailFolder?: string;
176
-
177
- /**
178
- * Custom Tailwind configuration
179
- * @default undefined
180
- */
181
- tailwindConfig?: TailwindConfig;
182
-
183
- /**
184
- * Enable debug logging
185
- * @default false
186
- */
187
- debug?: boolean;
188
- }
191
+ export const actions = {
192
+ ...createEmail,
193
+ ...sendEmail({
194
+ customSendEmailFunction: async ({ from, to, subject, html }) => {
195
+ // Use your preferred email service (SendGrid, Mailgun, etc.)
196
+ try {
197
+ await yourEmailService.send({ from, to, subject, html });
198
+ return { success: true };
199
+ } catch (error) {
200
+ return { success: false, error };
201
+ }
202
+ }
203
+ })
204
+ };
189
205
  ```
190
206
 
191
- ### Custom Tailwind Config
207
+ ## Configuration
208
+
209
+ Here are the available options:
192
210
 
193
211
  ```javascript
194
212
  betterSvelteEmailPreprocessor({
195
213
  pathToEmailFolder: '/src/lib/emails',
214
+ debug: false,
196
215
  tailwindConfig: {
197
216
  theme: {
198
217
  extend: {
@@ -205,12 +224,18 @@ betterSvelteEmailPreprocessor({
205
224
  });
206
225
  ```
207
226
 
227
+ ## Minimum Svelte Version
228
+
229
+ The minimum supported Svelte version is 5.14.3.
230
+ For older versions, you can use [`svelte-email-tailwind`](https://github.com/steveninety/svelte-email-tailwind).
231
+
208
232
  ## Supported Features
209
233
 
210
234
  ### ✅ Supported
211
235
 
212
236
  - ✅ Static Tailwind classes
213
- - ✅ All standard Tailwind utilities (colors, spacing, typography, etc.)
237
+ - ✅ Custom Tailwind classes (`bg-[#fff]`, `my:[40px]`, ...)
238
+ - ✅ All standard Tailwind (v3) utilities (colors, spacing, typography, etc.)
214
239
  - ✅ Responsive breakpoints (`sm:`, `md:`, `lg:`, `xl:`, `2xl:`)
215
240
  - ✅ HTML elements and Svelte components
216
241
  - ✅ Nested components
@@ -218,133 +243,24 @@ betterSvelteEmailPreprocessor({
218
243
  - ✅ Each blocks (`{#each}`)
219
244
  - ✅ Custom Tailwind configurations
220
245
 
221
- ### ❌ Not Supported (Yet)
246
+ ### ❌ Not Supported (Yet) (See [Roadmap](./ROADMAP.md))
222
247
 
248
+ - ❌ Tailwind v4
249
+ - ❌ CSS Object (`style={{ color: 'red' }}`)
223
250
  - ❌ Dynamic class expressions (`class={someVar}`)
224
251
  - ❌ Arbitrary values in responsive classes (`sm:[color:red]`)
225
252
  - ❌ Container queries
226
253
 
227
- ## API Reference
228
-
229
- ### Main Export
230
-
231
- ```typescript
232
- import { betterSvelteEmailPreprocessor } from 'better-svelte-email';
233
- ```
234
-
235
- ### Advanced Exports
236
-
237
- For advanced use cases, you can use individual functions:
238
-
239
- ```typescript
240
- import {
241
- parseClassAttributes,
242
- transformTailwindClasses,
243
- generateMediaQueries,
244
- injectMediaQueries
245
- } from 'better-svelte-email';
246
- ```
247
-
248
- ## Testing
249
-
250
- The library includes comprehensive tests:
251
-
252
- ```bash
253
- # Run all tests
254
- npm test
255
-
256
- # Run tests in watch mode
257
- npm run test:watch
258
-
259
- # Run tests with UI
260
- npm run test:ui
261
-
262
- # Run tests with coverage
263
- npm run test:coverage
264
- ```
265
-
266
- ## Examples
267
-
268
- ### Simple Button
269
-
270
- ```svelte
271
- <Button class="rounded bg-blue-500 px-4 py-2 text-white">Click Me</Button>
272
- ```
273
-
274
- ### Responsive Layout
275
-
276
- ```svelte
277
- <Container class="mx-auto w-full max-w-2xl p-4 sm:p-6 md:p-8">
278
- <Text class="text-lg sm:text-xl md:text-2xl">Responsive Text</Text>
279
- </Container>
280
- ```
281
-
282
- ### Complex Email
283
-
284
- ```svelte
285
- <Html>
286
- <Head />
287
- <Body class="bg-gray-100 font-sans">
288
- <Container class="mx-auto my-8 max-w-2xl rounded-lg bg-white shadow-lg">
289
- <Section class="p-8">
290
- <Text class="mb-4 text-3xl font-bold text-gray-900">Welcome to Our Service</Text>
291
-
292
- <Text class="mb-6 text-gray-600">
293
- Thank you for signing up. We're excited to have you on board!
294
- </Text>
295
-
296
- <Button
297
- href="https://example.com/verify"
298
- class="rounded-lg bg-blue-600 px-8 py-4 font-semibold text-white sm:bg-green-600"
299
- >
300
- Verify Your Email
301
- </Button>
302
- </Section>
303
- </Container>
304
- </Body>
305
- </Html>
306
- ```
307
-
308
- ## Troubleshooting
309
-
310
- ### Classes not being transformed
311
-
312
- 1. Make sure your file is in the configured `pathToEmailFolder`
313
- 2. Check that your classes are static strings, not dynamic expressions
314
- 3. Enable debug mode to see warnings: `{ debug: true }`
315
-
316
- ### Media queries not working
317
-
318
- 1. Ensure you have a `<Head />` component in your email
319
- 2. Check that you're using standard breakpoints (`sm:`, `md:`, etc.)
320
- 3. Verify the media queries are being injected (view the rendered HTML)
321
-
322
- ### Type errors
323
-
324
- Make sure you have the latest version of Svelte (requires 5.14.3 or higher):
325
-
326
- ```bash
327
- npm install svelte@latest
328
- ```
329
-
330
- ## Contributing
331
-
332
- Contributions are welcome! Please feel free to submit a Pull Request.
333
-
334
- ## License
335
-
336
- MIT
337
-
338
254
  ## Author
339
255
 
340
- Konixy
256
+ Anatole Dufour ([@Konixy](https://github.com/Konixy))
341
257
 
342
258
  ## Development
343
259
 
344
260
  ### Running Tests
345
261
 
346
262
  ```bash
347
- bun test
263
+ bun run test
348
264
  ```
349
265
 
350
266
  All tests must pass before pushing to main. The CI/CD pipeline will automatically run tests on every push and pull request.
@@ -357,36 +273,23 @@ bun run build
357
273
 
358
274
  ### Contributing
359
275
 
276
+ Contributions are welcome! Please feel free to submit a Pull Request.
277
+
278
+ To do so, you'll need to:
279
+
360
280
  1. Fork the repository
361
- 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
281
+ 2. Create a feature branch (`git checkout -b feat/amazing-feature`)
362
282
  3. Make your changes
363
- 4. Run tests (`bun test`)
283
+ 4. Run tests (`bun run test`)
364
284
  5. Commit your changes using [conventional commits](https://www.conventionalcommits.org/):
365
285
  - `feat:` - New features
366
286
  - `fix:` - Bug fixes
367
287
  - `docs:` - Documentation changes
368
288
  - `test:` - Test additions/changes
369
289
  - `chore:` - Maintenance tasks
370
- 6. Push to your branch (`git push origin feature/amazing-feature`)
290
+ 6. Push to your branch (`git push origin feat/amazing-feature`)
371
291
  7. Open a Pull Request
372
292
 
373
- ### Releases
374
-
375
- Releases are automated via GitHub Actions. When you bump the version in `package.json` and push to `main`, a new release will be automatically created with a generated changelog.
376
-
377
- See [RELEASE.md](./RELEASE.md) for detailed release process documentation.
378
-
379
- ## Acknowledgments
380
-
381
- - Built on top of [Svelte 5](https://svelte.dev/)
382
- - Uses [tw-to-css](https://github.com/dvkndn/tw-to-css) for Tailwind to CSS conversion
383
- - Uses [magic-string](https://github.com/rich-harris/magic-string) for efficient source transformations
384
-
385
- ## Related Projects
386
-
387
- - [react-email](https://react.email/) - React version for email templates
388
- - [svelte-email](https://github.com/carstenlebek/svelte-email) - Original Svelte email library
389
-
390
- ## Support
293
+ ## Acknowledgements
391
294
 
392
- If you find this project useful, please consider giving it a ⭐️ on GitHub!
295
+ Many components and logic were inspired by or adapted from [svelte-email-tailwind](https://github.com/steveninety/svelte-email-tailwind) and [react-email](https://react.email/). Huge thanks to the authors and contributors of these projects for their excellent work.