diff --git a/package.json b/package.json
index edcbec5..6710d91 100644
--- a/package.json
+++ b/package.json
@@ -50,8 +50,8 @@
"dependencies": {
"@nuxt/kit": "^3.10.0",
"defu": "^6.1.4",
- "vue-email": "^0.8.7",
- "@vue-email/compiler": "^0.8.9",
+ "vue-email": "npm:vue-email-edge@0.8.7-28446842.1f6e4a0",
+ "@vue-email/compiler": "npm:@vue-email/compiler-edge@0.8.9-28446863.0aab8eb",
"sirv": "^2.0.4"
},
"devDependencies": {
diff --git a/playground/nuxt-layer/emails/TestEmail.vue b/playground/nuxt-layer/emails/TestEmail.vue
index a87bce8..a239e99 100644
--- a/playground/nuxt-layer/emails/TestEmail.vue
+++ b/playground/nuxt-layer/emails/TestEmail.vue
@@ -1,156 +1,144 @@
-
-
- You're now ready to make live transactions with Stripe!
-
-
-
-
-
-
- Thanks for submitting your account information. You're now ready to make live transactions with Stripe!
+
+
+
+
+ .pager {display: none;} @media only screen and (max-width: 480px) {
+ .pager {display: block;} }
+
+
+ {{ previewText }}
+
+
+
+
+ Join {{ teamName }} on Vercel
+
+
+ Hello {{ username }},
-
- You can view your payments and a variety of other information about your account right from your dashboard.
+
+ {{ $vueEmail.baseUrl }}
-
- View your Stripe Dashboard
-
-
-
- If you haven't finished your integration, you might find our
+
+ bukinoshita (
- docs
+ {{ invitedByEmail }}
- handy.
+ ) has invited you to the {{ teamName }} team on
+ Vercel.
-
- Once you're ready to start accepting payments, you'll just need to use your live
-
- API keys
-
- instead of your test API keys. Your account can simultaneously be used for both test and live requests, so you can continue testing while accepting live payments. Check
- out our
-
- tutorial about account basics
-
- .
-
-
- Finally, we've put together a
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- quick checklist
-
- to ensure your website conforms to card network standards.
-
-
- We'll be here to help you with any step along the way. You can find answers to most questions and get in touch with us on our
+ Join the team
+
+
+
+ or copy and paste this URL into your browser:
- support site
+ {{ inviteLink }}
- .
-
-
- — The Stripe team
-
-
- Stripe, 354 Oyster Point Blvd, South San Francisco, CA 94080
+
+
+ This invitation was intended for
+ {{ username }} .This invite was sent
+ from {{ inviteFromIp }} located in
+ {{ inviteFromLocation }}. If you were not expecting this invitation, you can ignore this
+ email. If you are concerned about your account's safety, please
+ reply to this email to get in touch with us.
-
-
-
-
+
+
+
+
diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts
index c149ca6..0c20a78 100644
--- a/playground/nuxt.config.ts
+++ b/playground/nuxt.config.ts
@@ -1,27 +1,36 @@
export default defineNuxtConfig({
- modules: ['../src/module'],
- extends: [
- './nuxt-layer'
- ],
+ modules: ["../src/module", "@nuxtjs/tailwindcss"],
+ extends: ["./nuxt-layer"],
vueEmail: {
- baseUrl: 'https://vue-email-demo.vercel.app/',
+ baseUrl: "https://vue-email-demo.vercel.app/",
i18n: {
- defaultLocale: 'fr',
+ defaultLocale: "fr",
translations: {
en: {
- title: 'Welcome to Vue Email',
- subtitle: 'A Vue.js component for generating beautiful emails using MJML',
- button: 'Get Started',
+ title: "Welcome to Vue Email",
+ subtitle:
+ "A Vue.js component for generating beautiful emails using MJML",
+ button: "Get Started",
},
fr: {
- title: 'Bienvenue sur Vue Email',
- subtitle: 'Un composant Vue.js pour générer de beaux emails en utilisant MJML',
- button: 'Commencer',
+ title: "Bienvenue sur Vue Email",
+ subtitle:
+ "Un composant Vue.js pour générer de beaux emails en utilisant MJML",
+ button: "Commencer",
},
},
},
- autoImport: false
+ autoImport: false,
+ // tailwind: {
+ // theme: {
+ // extend: {
+ // colors: {
+ // primary: "#ea580c",
+ // secondary: "#ca8a04",
+ // },
+ // },
+ // },
+ // },
},
devtools: { enabled: true },
-
-})
+});
diff --git a/playground/package.json b/playground/package.json
index 5e00220..50b3643 100644
--- a/playground/package.json
+++ b/playground/package.json
@@ -10,6 +10,7 @@
"analyze": "nuxt analyze"
},
"devDependencies": {
+ "@nuxtjs/tailwindcss": "^6.11.2",
"nuxt": "latest"
}
}
diff --git a/playground/server/api/test.get.ts b/playground/server/api/test.get.ts
index 41eb8d5..2fc5773 100644
--- a/playground/server/api/test.get.ts
+++ b/playground/server/api/test.get.ts
@@ -1,20 +1,19 @@
-import { useCompiler } from '#vue-email'
+import { useCompiler } from "#vue-email";
export default defineEventHandler(async () => {
try {
- const template = await useCompiler('TestEmail.vue', {
+ const template = await useCompiler("TestEmail.vue", {
props: {
- username: 'Flowko',
+ username: "Flowko",
},
}).catch((error) => {
console.error(error);
- })
+ });
- if(!template) return null
+ if (!template) return null;
- return template.html
+ return template.html;
} catch (error) {
console.error(error);
-
}
-})
+});
diff --git a/playground/tailwind.config.js b/playground/tailwind.config.js
new file mode 100644
index 0000000..b89c848
--- /dev/null
+++ b/playground/tailwind.config.js
@@ -0,0 +1,13 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+ content: [],
+ theme: {
+ extend: {
+ colors: {
+ primary: "cyan",
+ secondary: "#ca8a04",
+ },
+ },
+ },
+ plugins: [],
+};
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 12a6f40..f77afec 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -12,8 +12,8 @@ importers:
specifier: ^3.10.0
version: 3.10.0(rollup@3.29.4)
'@vue-email/compiler':
- specifier: ^0.8.9
- version: 0.8.9(typescript@5.3.3)(vue@3.4.15)
+ specifier: npm:@vue-email/compiler-edge@0.8.9-28446863.0aab8eb
+ version: /@vue-email/compiler-edge@0.8.9-28446863.0aab8eb(typescript@5.3.3)(vue@3.4.15)
defu:
specifier: ^6.1.4
version: 6.1.4
@@ -21,8 +21,8 @@ importers:
specifier: ^2.0.4
version: 2.0.4
vue-email:
- specifier: ^0.8.7
- version: 0.8.7(typescript@5.3.3)(vue@3.4.15)
+ specifier: npm:vue-email-edge@0.8.7-28446842.1f6e4a0
+ version: /vue-email-edge@0.8.7-28446842.1f6e4a0(typescript@5.3.3)(vue@3.4.15)
devDependencies:
'@nuxt/devtools':
specifier: latest
@@ -123,6 +123,9 @@ importers:
playground:
devDependencies:
+ '@nuxtjs/tailwindcss':
+ specifier: ^6.11.2
+ version: 6.11.2(rollup@3.29.4)
nuxt:
specifier: latest
version: 3.9.3(@types/node@20.11.10)(eslint@8.56.0)(rollup@3.29.4)(typescript@5.3.3)(vite@5.0.12)
@@ -1960,6 +1963,31 @@ packages:
- ts-node
dev: true
+ /@nuxtjs/tailwindcss@6.11.2(rollup@3.29.4):
+ resolution: {integrity: sha512-06e8t9ia6Ru/RPMATuhGwi16rMYeZPseXiI4QmRDk/IkvluU60GxhLZOjdUIa+U7DVCECgDsRNEo/rD8/1sMKQ==}
+ dependencies:
+ '@nuxt/kit': 3.10.0(rollup@3.29.4)
+ autoprefixer: 10.4.17(postcss@8.4.33)
+ chokidar: 3.5.3
+ clear-module: 4.1.2
+ colorette: 2.0.20
+ consola: 3.2.3
+ defu: 6.1.4
+ h3: 1.10.1
+ micromatch: 4.0.5
+ pathe: 1.1.2
+ postcss: 8.4.33
+ postcss-custom-properties: 13.3.4(postcss@8.4.33)
+ postcss-nesting: 12.0.2(postcss@8.4.33)
+ tailwind-config-viewer: 1.7.3(tailwindcss@3.4.1)
+ tailwindcss: 3.4.1
+ ufo: 1.3.2
+ transitivePeerDependencies:
+ - rollup
+ - supports-color
+ - ts-node
+ dev: true
+
/@one-ini/wasm@0.1.1:
resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
dev: true
@@ -2465,6 +2493,10 @@ packages:
selderee: 0.11.0
dev: true
+ /@shikijs/core@1.0.0-beta.1:
+ resolution: {integrity: sha512-z3gdznaRj/DJSLQdR2Gdx6AB3e5+Il/kSGdLTGHI7HnalgPL15RbGgBSdLHW8rKAz4+dezAcTdnxm8z6YTu7nA==}
+ dev: false
+
/@sigstore/bundle@2.1.1:
resolution: {integrity: sha512-v3/iS+1nufZdKQ5iAlQKcCsoh0jffQyABvYIxKsZQFWc4ubuGjwZklFHpDgV6O6T7vvV78SW5NHI91HFKEcxKg==}
engines: {node: ^16.14.0 || >=18.0.0}
@@ -2937,8 +2969,8 @@ packages:
pretty-format: 29.7.0
dev: true
- /@vue-email/cli@0.0.10(typescript@5.3.3)(vue@3.4.15):
- resolution: {integrity: sha512-F99FOPQ8++SGJ8toAqboiW78o2d9ZDMmh7B9x8OZBvHyq/cH4KZca3VCQ9JaaOX4Rrovu6R3mwdPgJhtfK+l8A==}
+ /@vue-email/cli@0.0.11(typescript@5.3.3)(vue@3.4.15):
+ resolution: {integrity: sha512-nPOiCwRYc0Z3BIsTJ1rnFNcQaJQ2iE1QB/GaHVMR0fxM72VB0qcQ/LsrMDgvewAgY1ZJkpGGVrwwIR7T6PEU/w==}
hasBin: true
dependencies:
'@vue-email/compiler': 0.8.9(typescript@5.3.3)(vue@3.4.15)
@@ -2952,6 +2984,25 @@ packages:
- vue
dev: false
+ /@vue-email/compiler-edge@0.8.9-28446863.0aab8eb(typescript@5.3.3)(vue@3.4.15):
+ resolution: {integrity: sha512-PxPJifTQGqHCK0gK4yBt05dzyArfMAj467wSJ8JL7YMZvELXlG/cMDkRC6nQ1PexiFCdTQnsjW5akAwWTVDGhQ==}
+ peerDependencies:
+ vue: ^3.3.8
+ dependencies:
+ import-string: 0.1.2(typescript@5.3.3)
+ kolorist: 1.8.0
+ scule: 1.2.0
+ vue: 3.4.15(typescript@5.3.3)
+ vue-email: /vue-email-edge@0.8.7-28446842.1f6e4a0(typescript@5.3.3)(vue@3.4.15)
+ transitivePeerDependencies:
+ - bufferutil
+ - canvas
+ - supports-color
+ - ts-node
+ - typescript
+ - utf-8-validate
+ dev: false
+
/@vue-email/compiler@0.8.9(typescript@5.3.3)(vue@3.4.15):
resolution: {integrity: sha512-5sHZiK/jQ/cDgCOAlenO7LZjN5DpAnnUsA7RX5n+xgMW/HrrBO2x1l9Za20TuH09CPmpePPIVGoT8DACA08IjQ==}
peerDependencies:
@@ -8077,6 +8128,12 @@ packages:
resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==}
dev: true
+ /shiki@1.0.0-beta.1:
+ resolution: {integrity: sha512-iq32WxjemJVlAHg5HjYoL1qCxGmvyh3Z8kr2E/gMTQdcxyXxTpMhahIC7myxFBapAk9o8QN8mxCpr4JT5rqpRQ==}
+ dependencies:
+ '@shikijs/core': 1.0.0-beta.1
+ dev: false
+
/shikiji-core@0.10.2:
resolution: {integrity: sha512-9Of8HMlF96usXJHmCL3Gd0Fcf0EcyJUF9m8EoAKKd98mHXi0La2AZl1h6PegSFGtiYcBDK/fLuKbDa1l16r1fA==}
dev: false
@@ -9410,13 +9467,35 @@ packages:
resolution: {integrity: sha512-RutnB7X8c5hjq39NceArgXg28WZtZpGc3+J16ljMiYnFhKvd8hITxSWQSQ5bvldxMDU6gG5mkxl1MTQLXckVSQ==}
dev: true
+ /vue-email-edge@0.8.7-28446842.1f6e4a0(typescript@5.3.3)(vue@3.4.15):
+ resolution: {integrity: sha512-tYhsDpxH+Ds93vk32TKdFrg3fx8p24wxvu+EA1zFuaJCH2YJzHyklcDI5M2+yu1yOFofi+mGbW5jV+NmeAuUXA==}
+ hasBin: true
+ peerDependencies:
+ vue: ^3.4.15
+ dependencies:
+ '@vue-email/cli': 0.0.11(typescript@5.3.3)(vue@3.4.15)
+ '@vue-email/tailwind': 0.0.6
+ isomorphic-dompurify: 2.3.0
+ shiki: 1.0.0-beta.1
+ ufo: 1.3.2
+ vue: 3.4.15(typescript@5.3.3)
+ vue-i18n: 9.9.0(vue@3.4.15)
+ transitivePeerDependencies:
+ - bufferutil
+ - canvas
+ - supports-color
+ - ts-node
+ - typescript
+ - utf-8-validate
+ dev: false
+
/vue-email@0.8.7(typescript@5.3.3)(vue@3.4.15):
resolution: {integrity: sha512-VxJHqXpVnFIezZ4Oj+vhtjBNBQZtqbKud+WicLQLSIqdtcV9hnM6f3+BQIXW2AijglVCTtUel/Z2Tn1m7/teRA==}
hasBin: true
peerDependencies:
vue: ^3.4.15
dependencies:
- '@vue-email/cli': 0.0.10(typescript@5.3.3)(vue@3.4.15)
+ '@vue-email/cli': 0.0.11(typescript@5.3.3)(vue@3.4.15)
'@vue-email/tailwind': 0.0.6
isomorphic-dompurify: 2.3.0
shikiji: 0.10.2
diff --git a/src/module.ts b/src/module.ts
index 6248f72..2516b28 100644
--- a/src/module.ts
+++ b/src/module.ts
@@ -8,10 +8,11 @@ import {
addTemplate,
createResolver,
defineNuxtModule,
+ hasNuxtModule,
} from "@nuxt/kit";
import { defu } from "defu";
import sirv from "sirv";
-import type { I18n } from "vue-email";
+import type { I18n, VueEmailPluginOptions } from "vue-email";
const components = [
"EBody",
@@ -44,6 +45,8 @@ export interface ModuleOptions {
i18n?: I18n;
playground?: boolean;
autoImport?: boolean;
+ useNuxtTailwind?: boolean;
+ tailwind?: VueEmailPluginOptions["tailwind"];
}
export default defineNuxtModule({
@@ -63,6 +66,8 @@ export default defineNuxtModule({
baseUrl: null,
playground: isDev,
autoImport: false,
+ useNuxtTailwind: true,
+ tailwind: undefined,
};
},
async setup(options, nuxt) {
@@ -85,6 +90,17 @@ export default defineNuxtModule({
break;
}
+ if (hasNuxtModule("@nuxtjs/tailwindcss") && options.useNuxtTailwind) {
+ // @ts-ignore
+ nuxt.hook("tailwindcss:resolvedConfig", function (resolvedConfig) {
+ options.tailwind = resolvedConfig;
+ nuxt.options.runtimeConfig.public.vueEmail = defu(
+ nuxt.options.runtimeConfig.public.vueEmail,
+ options
+ );
+ });
+ }
+
nuxt.options.nitro.alias = nuxt.options.nitro.alias || {};
nuxt.options.nitro.externals = defu(
typeof nuxt.options.nitro.externals === "object"
diff --git a/src/runtime/server/nitro/useCompiler.ts b/src/runtime/server/nitro/useCompiler.ts
index 7c8c035..2300637 100644
--- a/src/runtime/server/nitro/useCompiler.ts
+++ b/src/runtime/server/nitro/useCompiler.ts
@@ -1,9 +1,9 @@
-import type { RenderOptions } from '@vue-email/compiler'
-import { templateRender } from '@vue-email/compiler'
-import type { ModuleOptions } from '../../../module'
-import { useRuntimeConfig, useStorage } from '#imports'
+import type { RenderOptions } from "@vue-email/compiler";
+import { templateRender } from "@vue-email/compiler";
+import type { ModuleOptions } from "../../../module";
+import { useRuntimeConfig, useStorage } from "#imports";
-const storageKey = 'assets:emails'
+const storageKey = "assets:emails";
/**
* Compile a email template
@@ -22,34 +22,44 @@ const storageKey = 'assets:emails'
* })
* ```
*/
-export async function useCompiler(filename: string, data?: RenderOptions, verbose = false) {
- const vueEmailOptions = useRuntimeConfig().public.vueEmail as ModuleOptions
- const source = await useStorage(storageKey).getItem(filename)
- const keys = await useStorage(storageKey).getKeys()
+export async function useCompiler(
+ filename: string,
+ data?: RenderOptions,
+ verbose = false
+) {
+ const vueEmailOptions = useRuntimeConfig().public.vueEmail as ModuleOptions;
+ const source = await useStorage(storageKey).getItem(filename);
+ const keys = await useStorage(storageKey).getKeys();
const components: {
- name: string
- source: string
- }[] = []
+ name: string;
+ source: string;
+ }[] = [];
for (const key of keys) {
- const value = await useStorage(storageKey).getItem(key)
+ const value = await useStorage(storageKey).getItem(key);
- if (value && key.endsWith('.vue')) {
+ if (value && key.endsWith(".vue")) {
components.push({
name: key,
source: value as string,
- })
+ });
}
}
- if(!source) throw new Error(`Template ${filename} not found`)
+ if (!source) throw new Error(`Template ${filename} not found`);
- const template = await templateRender(filename, { source: source as string, components }, data, {
- verbose,
- options: {
- baseUrl: vueEmailOptions?.baseUrl,
- i18n: vueEmailOptions?.i18n,
- },
- })
+ const template = await templateRender(
+ filename,
+ { source: source as string, components },
+ data,
+ {
+ verbose,
+ options: {
+ baseUrl: vueEmailOptions?.baseUrl,
+ i18n: vueEmailOptions?.i18n,
+ tailwind: vueEmailOptions?.tailwind,
+ },
+ }
+ );
- return template
+ return template;
}