nuxt-generation-emails 0.2.4 → 0.2.6

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/README.md CHANGED
@@ -56,7 +56,7 @@ export default defineNuxtConfig({
56
56
 
57
57
  ---
58
58
 
59
- ## �️ 2. Adding Templates with the CLI
59
+ ## 🛠️ 2. Adding Templates with the CLI
60
60
 
61
61
  The fastest way to create a new email template:
62
62
 
@@ -174,7 +174,27 @@ The directory structure maps directly to routes:
174
174
 
175
175
  ## ✍️ 4. Writing Email Templates
176
176
 
177
- Templates are standard Vue SFCs using [`@vue-email/components`](https://vuemail.net/). Define your template's dynamic data using `defineProps` with `withDefaults`:
177
+ Templates are standard Vue SFCs built with [`@vue-email/components`](https://vuemail.net/) — a set of unstyled, email-safe Vue components that produce clean, cross-client HTML. Instead of wrestling with `<table>` layouts and inline styles, you use components like `<Container>`, `<Section>`, `<Text>`, `<Button>`, and `<Heading>` that compile down to battle-tested email markup. The `<Tailwind>` wrapper lets you style with Tailwind CSS utility classes that get inlined automatically at render time.
178
+
179
+ Key components from `@vue-email/components`:
180
+
181
+ | Component | Purpose |
182
+ |----------------|-------------------------------------------------------------------------|
183
+ | `<Html>` | Root email wrapper with `lang` attribute |
184
+ | `<Head>` | Email `<head>` — inject fonts, meta tags |
185
+ | `<Body>` | Email body element |
186
+ | `<Container>` | Centered, max-width content wrapper (replaces `<table>` centering hacks)|
187
+ | `<Section>` | Groups content into rows |
188
+ | `<Text>` | Paragraph text with sensible email defaults |
189
+ | `<Heading>` | `<h1>`–`<h6>` headings |
190
+ | `<Button>` | Call-to-action link styled as a button |
191
+ | `<Hr>` | Horizontal rule |
192
+ | `<Link>` | Anchor tag |
193
+ | `<Preview>` | Invisible preheader text shown in inbox previews |
194
+ | `<Font>` | Web font loading via `@font-face` |
195
+ | `<Tailwind>` | Wraps the template to enable Tailwind CSS utility classes |
196
+
197
+ Define your template's dynamic data using `defineProps` with `withDefaults`:
178
198
 
179
199
  ```vue
180
200
  <script setup lang="ts">
@@ -359,12 +379,22 @@ curl -X POST http://localhost:3000/api/emails/v1/order-confirmation \
359
379
 
360
380
  ## 🔧 7. Module Options
361
381
 
362
- | Option | Type | Default | Description |
363
- |------------------|------------|------------|--------------------------------------------------------------------|
364
- | `emailDir` | `string` | `'emails'` | Directory containing email templates (relative to `srcDir`) |
382
+ | Option | Type | Default | Description |
383
+ |-----------------------|------------|------------|--------------------------------------------------------------------|
384
+ | `emailDir` | `string` | `'emails'` | Directory containing email templates (relative to `srcDir`) |
385
+ | `disablePreviewInProd` | `boolean` | `true` | When `true`, the `/__emails/` preview UI is not registered in production builds. API routes are unaffected. |
365
386
 
366
387
  Full config key: `nuxtGenerationEmails`
367
388
 
389
+ ```ts
390
+ export default defineNuxtConfig({
391
+ nuxtGenerationEmails: {
392
+ emailDir: 'emails',
393
+ disablePreviewInProd: true, // default — preview pages are dev-only
394
+ },
395
+ })
396
+ ```
397
+
368
398
  ### Nitro hook
369
399
 
370
400
  | Hook | Payload | Description |
@@ -373,7 +403,44 @@ Full config key: `nuxtGenerationEmails`
373
403
 
374
404
  ---
375
405
 
376
- ## 🧩 Auto-Imports
406
+ ## 🔒 8. Securing API Endpoints
407
+
408
+ The generated `POST /api/emails/...` endpoints are registered in all environments (dev and production). In production, you should protect them with server middleware to prevent unauthorized access.
409
+
410
+ ### Using Nuxt server middleware
411
+
412
+ Create a server middleware file that gates access to the email API routes:
413
+
414
+ ```ts
415
+ // server/middleware/protect-emails.ts
416
+ import { defineEventHandler, createError, getHeader } from 'h3'
417
+
418
+ export default defineEventHandler((event) => {
419
+ // Only apply to email API routes
420
+ if (!event.path?.startsWith('/api/emails/')) return
421
+
422
+ const apiKey = getHeader(event, 'x-api-key')
423
+
424
+ if (apiKey !== process.env.EMAIL_API_KEY) {
425
+ throw createError({ statusCode: 401, statusMessage: 'Unauthorized' })
426
+ }
427
+ })
428
+ ```
429
+
430
+ Then set `EMAIL_API_KEY` in your environment and include the header in requests:
431
+
432
+ ```bash
433
+ curl -X POST http://localhost:3000/api/emails/v1/order-confirmation \
434
+ -H "Content-Type: application/json" \
435
+ -H "x-api-key: your-secret-key" \
436
+ -d '{ "templateData": {}, "sendData": {} }'
437
+ ```
438
+
439
+ You can also use session-based auth, JWT validation, or any other pattern — the middleware runs before the generated route handler so you have full control.
440
+
441
+ ---
442
+
443
+ ## 🧩 9. Auto-Imports
377
444
 
378
445
  The module auto-imports these utilities for convenience:
379
446
 
package/dist/module.d.mts CHANGED
@@ -19,6 +19,8 @@ interface NuxtGenEmailsSendPayload<TSendData extends Record<string, unknown> = N
19
19
  interface ModuleOptions {
20
20
  /** Directory containing email templates; resolved from srcDir when relative. */
21
21
  emailDir?: string;
22
+ /** When true, the `/__emails/` preview UI pages are not registered in production builds. API routes are unaffected. Defaults to `true`. */
23
+ disablePreviewInProd?: boolean;
22
24
  }
23
25
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
24
26
 
package/dist/module.d.ts CHANGED
@@ -19,6 +19,8 @@ interface NuxtGenEmailsSendPayload<TSendData extends Record<string, unknown> = N
19
19
  interface ModuleOptions {
20
20
  /** Directory containing email templates; resolved from srcDir when relative. */
21
21
  emailDir?: string;
22
+ /** When true, the `/__emails/` preview UI pages are not registered in production builds. API routes are unaffected. Defaults to `true`. */
23
+ disablePreviewInProd?: boolean;
22
24
  }
23
25
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
24
26
 
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=4.0.0"
6
6
  },
7
- "version": "0.2.4",
7
+ "version": "0.2.6",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -421,7 +421,8 @@ const module$1 = defineNuxtModule({
421
421
  }
422
422
  },
423
423
  defaults: {
424
- emailDir: "emails"
424
+ emailDir: "emails",
425
+ disablePreviewInProd: true
425
426
  },
426
427
  async setup(options, nuxt) {
427
428
  const resolver = createResolver(import.meta.url);
@@ -480,15 +481,18 @@ declare module 'nitropack/types' {
480
481
  from: resolver.resolve("./runtime/utils/url-params")
481
482
  }
482
483
  ]);
483
- extendPages((pages) => {
484
- if (!fs.existsSync(emailsDir)) {
485
- return;
486
- }
487
- addEmailPages(emailsDir, pages, {
488
- buildDir: nuxt.options.buildDir,
489
- emailTemplateComponentPath: resolver.resolve("./runtime/pages/__emails.vue")
484
+ const shouldRegisterPreview = nuxt.options.dev || !options.disablePreviewInProd;
485
+ if (shouldRegisterPreview) {
486
+ extendPages((pages) => {
487
+ if (!fs.existsSync(emailsDir)) {
488
+ return;
489
+ }
490
+ addEmailPages(emailsDir, pages, {
491
+ buildDir: nuxt.options.buildDir,
492
+ emailTemplateComponentPath: resolver.resolve("./runtime/pages/__emails.vue")
493
+ });
490
494
  });
491
- });
495
+ }
492
496
  const handlers = generateServerRoutes(emailsDir, nuxt.options.buildDir);
493
497
  for (const handler of handlers) {
494
498
  addServerHandler({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-generation-emails",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "A Nuxt module for authoring, previewing, and sending transactional email templates with Vue Email.",
5
5
  "author": "nullcarry@icloud.com",
6
6
  "repository": {