Development
Dynamic Imports using Nitro virtual modules
How the Vue SFC email templates are dynamically imported and rendered using Nitro virtual modules.
This modules provides a robust approach to rendering full Vue Single File Components (SFC) as email templates by leveraging Nuxt's build system and virtual modules.
How It Works
1. Build-Time Template Discovery
- During the Nuxt build process, the module scans the configured
emailsdirectory - It discovers all
.vuefiles and generates metadata for each template - Creates a virtual Nitro module that imports all discovered templates
2. Virtual Module Generation
The virtual module (#email-templates) contains:
import AwsVerifyEmail from "/path/to/emails/AwsVerifyEmail.vue";
import Newsletter from "/path/to/emails/Newsletter.vue";
// ... other templates
export const emailTemplates = {
AwsVerifyEmail: AwsVerifyEmail,
Newsletter: Newsletter,
// ...
};
export const emailTemplateMapping = {
AwsVerifyEmail: {
name: "AwsVerifyEmail",
filename: "AwsVerifyEmail.vue",
displayName: "Aws Verify Email",
importPath: "#email-templates/AwsVerifyEmail",
filePath: "/path/to/emails/AwsVerifyEmail.vue",
},
// ...
};
3. Runtime Template Resolution
- Server endpoints use the template resolver utility
- Templates are accessed by name through the virtual module
- Full SFC compilation is handled by Nuxt/Nitro automatically
4. Development API Endpoints
API endpoints are only available in development mode and are used exclusively by Nuxt DevTools. They are automatically disabled in production to prevent exposing email templates publicly.
GET /api/emails- Returns template metadata (dev-only, for DevTools)POST /api/emails/render- Renders templates using compiled Vue components (dev-only, for DevTools)POST /api/emails/source- Returns template source code (dev-only, for DevTools)
For production use, use the renderEmailComponent function in your server-side code instead.
Benefits
✅ Complete SFC Support
- Script Setup: All reactive data, computed properties, and composition API features work
- Styles: Scoped styles and CSS modules are properly handled
- TypeScript: Full TypeScript support with proper type checking
- Props: Component props are properly typed and validated
✅ Performance
- Templates are compiled at build time, not runtime
- No need to parse Vue SFC syntax on every request
- Virtual modules are cached and optimized by Nitro
✅ Developer Experience
- Hot reloading works in development
- Full IDE support with proper imports and type checking
- No need to duplicate template logic
✅ Maintainability
- Clean separation between build-time discovery and runtime rendering
- Easy to extend with additional metadata or features
- Robust error handling for missing templates
Architecture Flow
- Build Time:
emails/ ├── WelcomeEmail.vue ├── PasswordReset.vue └── Newsletter.vue ↓ Module scans directory Virtual Module (#email-templates) ├── imports all .vue files ├── creates component mapping └── exports template utilities - Runtime:
API Request → Template Resolver → Virtual Module → Full Vue Component → SSR Render → HTML Output
This approach provides the best balance of functionality, performance, and maintainability while leveraging Nuxt's existing infrastructure.