vue-email / vue-email Goto Github PK
View Code? Open in Web Editor NEW💌 Write email templates with vue
Home Page: https://vuemail.net
License: MIT License
💌 Write email templates with vue
Home Page: https://vuemail.net
License: MIT License
Hi, I can't seem to get the template compiler on production, on a Nuxt 3 app hosted on vercel (latest release of vue-email)
🚧 Compiling InvitationEmail file
💌 Generating output
🚧 Compiling InvitationEmail file
🌎 Injecting translations
🎉 Rendering template InvitationEmail
Unhandled Promise Rejection {"errorType":"Runtime.UnhandledPromiseRejection","errorMessage":"ReferenceError: __VUE_PROD_DEVTOOLS__ is not defined","reason":{"errorType":"ReferenceError","errorMessage":"__VUE_PROD_DEVTOOLS__ is not defined","stack":["ReferenceError: __VUE_PROD_DEVTOOLS__ is not defined"," at Object.install (file:///var/task/node_modules/@vue-email/compiler/dist/chunks/vue-i18n.mjs:5858:65)"," at Object.use (/var/task/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js:2892:18)"," at templateRender (file:///var/task/node_modules/@vue-email/compiler/dist/compiler.mjs:223:11)"," at async renderEmailTemplate (file:///var/task/chunks/_trpc_.mjs:2059:10)"," at async sendInvitationEmail (file:///var/task/chunks/_trpc_.mjs:2080:13)"," at async resolveMiddleware (file:///var/task/chunks/_trpc_.mjs:1013:30)"," at async callRecursive (file:///var/task/chunks/_trpc_.mjs:1049:32)"," at async callRecursive (file:///var/task/chunks/_trpc_.mjs:1049:32)"," at async callRecursive (file:///var/task/chunks/_trpc_.mjs:1049:32)"," at async resolve (file:///var/task/chunks/_trpc_.mjs:1079:24)"]},"promise":{},"stack":["Runtime.UnhandledPromiseRejection: ReferenceError: __VUE_PROD_DEVTOOLS__ is not defined"," at process.<anonymous> (file:///var/runtime/index.mjs:1276:17)"," at process.emit (node:events:529:35)"," at emit (node:internal/process/promises:149:20)"," at processPromiseRejections (node:internal/process/promises:283:27)"," at process.processTicksAndRejections (node:internal/process/task_queues:96:32)"]}
Unknown application error occurred
Runtime.Unknown
Everything works fine locally, even if I build locally & run the build output, still no issues. Not too sure what other information might help you, but here's at least the nuxt info
Config : Nuxt 3.6.5, Node 18, Firebase 12.9.1
I have tried to use Vue Email and MailerSend Node.js SDK. When I deploy my project on firebase hosting, I have following error message :
Function failed on loading user code. This is likely due to a bug in the user code. Error message: Provided module can't be loaded.
Did you list all required modules in the package.json dependencies?
Detailed stack trace: Error: Cannot find module 'vue/compiler-sfc'
Require stack:
So far, my functions/index.js looks like :
const { MailerSend, EmailParams, Sender, Recipient } = require('mailersend');
const { config } = require('@vue-email/compiler');
...
const mailerSend = new MailerSend({
apiKey: functions.config().mailersend.api_key,
});
const vueEmail = config("./templates");
async function sendEmail(emailData) {
const { to, name, subject } = emailData;
const sentFrom = new Sender("*****", "*****");
const recipients = [new Recipient(to, name)];
const template = await vueEmail.render("Welcome.vue", {
props: {
url: 'https://vuemail.net/',
},
});
const emailParams = new EmailParams()
.setFrom(sentFrom)
.setTo(recipients)
.setSubject(subject)
.setHtml(template);
try {
await mailerSend.email.send(emailParams);
return { message: "Email sent" };
} catch (error) {
console.error("Error sending email:", error);
throw new functions.https.HttpsError('unknown', 'Failed to send email');
}
};
My functions/templates/Welcome.vue looks like :
<template>
<e-html lang="en">
<e-button :href="url">
View on GitHub
</e-button>
</e-html>
</template>
<script setup>
const props = defineProps({
url: String,
})
</script>
And my functions/package.json looks like :
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "18"
},
"main": "index.js",
"dependencies": {
"@vue-email/compiler": "^0.8.0-beta.4",
"firebase-admin": "^11.11.0",
"firebase-functions": "^4.5.0",
"mailersend": "^2.2.0",
},
"devDependencies": {
"firebase-functions-test": "^3.1.0"
},
"private": true
}
Am I missing something ?
Hello,
Is it possible to add a 'style' tag with media queries to manage behavior based on window width?
Hi, just tried to install it, but Nuxt cannot find the module:
Error while requiring module vue-email/nuxt: Error: Cannot find module 'myproject/vue-email/nuxt'
When downgraded to 0.7.2 it works now.
I know UnoCSS is a slight wrapper of Tailwind, but I wondered want the feasibility is to add UnoCSS as another supported CSS utility library?
Hello
I have been reported a bug with the version of safari on iOS (<16).
I found this PR #85 and I also noticed that in version v0.8.0-beta.5 it comes out as fixed.
I have updated to version v0.8.0-beta.5 but the same problem shown in the image persists, I tried on the playground page and also comes out the error (I don't know if the playground is updated but I got the same message before updating).
I don't think it's another dependency since I tried removing the vue-email beta 5 module (from my nuxt app) and the page loaded normally.
Regards
first, thanks for this awesome library.
i would like to help and improve this library, but im facing issues to run it locally, can u include a contributing guide, on the commands and packages that needs to be executed ?
Currently, the dependencies such as isomorphic-dompurify
are not externalized by Vite.
This causes issues when using the lib in an SSR context as the bundled isomorphic-dompurify
requires the window
object.
Add isomorphic-dompurify
and other deps to be externalized.
Would be happy to open a PR for this! (:
I would love to organize my emails based on folders then it render the tree on the left side bar.
Folder emails/
= "All Emails"
Folder emails/Company/newsletter.vue
This could be useful as it helps organize it and doesn't contain everything in on subfolder within the view.
Hello,
I would like to use my own components. I have created a file in the 'components' folder, but the system completely ignores it.
Is there a way to do this?
Basic install using vite/vue3
Template:
<script setup>
import { ref } from 'vue';
import {
ETailwind,
EHtml, EHead, EPreview, EBody,
EContainer, ESection, EColumn, ERow,
EText, EHeading, EButton, EImg
} from 'vue-email';
defineProps({
title: String,
});
const tailwindConfig = ref({
theme: {
extend: {}
},
});
</script>
<template>
<ETailwind>
<EHtml>
<EHead />
<EPreview>Yelp recent login</EPreview>
<EBody>
<EContainer>
<ESection class="mb-6">
<EImg src="https://vue-email-demo.vercel.app/static/yelp-logo.png" />
</ESection>
<ESection :style="content">
<EImg width="620" src="https://vue-email-demo.vercel.app/static/yelp-header.png" />
<ERow>
<EColumn>
<EHeading style="font-size: 32; font-weight: bold; text-align: center"> Hi {{ userFirstName }}, </EHeading>
<EHeading as="h2">
We noticed a recent login to your Yelp account.
</EHeading>
<EText>
<b>Time: </b>
{{ formattedDate }}
</EText>
<EText>
<b>Device: </b>
{{ loginDevice }}
</EText>
<EText>
<b>Location: </b>
{{ loginLocation }}
</EText>
<EText>
*Approximate geographic location based on IP address: {loginIp}
</EText>
<EText> If this was you, there's nothing else you need to do. </EText>
<EText> If this wasn't you or if you have additional questions, please see our support page. </EText>
</EColumn>
</ERow>
<ERow>
<EColumn col-span="{2}">
<EButton href="#"> Learn More </EButton>
</EColumn>
</ERow>
</ESection>
<ESection>
<EImg width="620" src="https://vue-email-demo.vercel.app/static/yelp-footer.png" />
</ESection>
<EText>
© 2022 | Yelp Inc., 350 Mission Street, San Francisco, CA 94105, U.S.A. | www.yelp.com
</EText>
</EContainer>
</EBody>
</EHtml>
</ETailwind>
</template>
Any idea why this is happening?
Currently my emails
directory looks like this.
emails
│ Message.vue
│ Welcome.vue
│
└───designer
├───components
│ Footer.vue
│ Header.vue
│ Unsubscribe.vue
│
└───layouts
Default.vue
All components are autoimported correctly (I am able to use <DesignerComponentsFooter />
in templates.
But, while using useCompiler(...)
the components are not found.
If I use <DesignerComponents:Footer />
in my templates, then useCompiler(...)
works fine but then regular nuxt rendering is not working.
Config : Nuxt 3.6.5, Node 18, Firebase 12.9.1
I am using Vue Email and MailerSend Node.js SDK. I wrote a firebase cloud function to send emails. The emails are properly sent but I get following error in the console : ReferenceError: VUE_PROD_DEVTOOLS is not defined and it stops the execution of my function.
Do you know from where it comes from ? Should I install Nuxt Devtools in my firebase cloud functions environment ? It seems a bit akward since it is a visual tool.
Here is my package.json :
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"serve": "firebase emulators:start --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "18"
},
"main": "index.js",
"dependencies": {
"@vue-email/compiler": "^0.8.0-beta.4",
"firebase-admin": "^11.11.0",
"firebase-functions": "^4.5.0",
"vue": "^3.3.8"
},
"devDependencies": {
"firebase-functions-test": "^3.1.0"
},
"private": true
}
Add support to nuxt devtools https://devtools.nuxtjs.org/
this will allow users to preview and send emails directly from their devtools
The main goal is render components on server side
Proposal:
import express from 'express';
import { createEmail } from 'vue-email';
const app = express();
const email = createEmail({
path: './path/to/templates',
});
app.get('/send', async (req, res) => {
const template = await email.render('template-name', {
props: {
name: req.body.name,
}
});
await sendEmail({
cc: 'x',
html: template,
});
return res.send('Sent');
});
I am primarily interested in an export
command which will render all emails. Similar to the react-email CLI.
[nuxt] [request error] [unhandled] [500] 'import' statement of ES modules is not supported
Use asynchronous function 'importFromString' instead or replace it with dynamic 'import()' expression.
at Module.importFromStringSync (./node_modules/module-from-string/dist/index.mjs:267:13)
at templateRender (./.nuxt/dev/index.mjs:9437:102)
at useCompiler (./.nuxt/dev/index.mjs:9515:26)
at async eval (./.nuxt/dev/index.mjs:9530:16)
at async Object.eval (./node_modules/h3/dist/index.mjs:1386:19)
at async Server.toNodeHandle (./node_modules/h3/dist/index.mjs:1461:7)
reproduction:
https://github.com/v-moravec/nuxt-vue-email/
https://stackblitz.com/edit/github-9eaosg?file=emails%2FOptilynx.vue
found by:
@v-moravec
related:
#48
Classes translation to inline styles is not intuitive and when there is inheritance expected, it will behave unexpectly. Also Tailwind text size classes does not override default font-size.
<template>
<e-html lang="cs">
<e-tailwind>
<div class="text-center text-base">
<e-text class="text-base">Only this text have text-base applied</e-text>
<e-text>This text should have text-base applied, but does not.</e-text>
</div>
</e-tailwind>
</e-html>
</template>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html id="__vue-email" lang="cs" dir="ltr">
<div style=" font-size:1rem;line-height:1.5rem;text-align:center">
<p data-id="__vue-email-text" style="font-size:14px;line-height:24px;margin:16px 0; font-size:1rem;line-height:1.5rem">Only this text have text-base applied</p>
<p data-id="__vue-email-text" style="font-size: 14px; line-height: 24px; margin: 16px 0;">This text should have text-base applied, but does not.</p>
</div>
</html>
If it cannot be fixed, there should be easy to understand explanation in docs.
I have installed this package as is in a project.
And i saw too create a email you need to write the css and layout in every template.
I was not able to find how to import a custom component inside the email template.
When i tried i got the following error
[Vue warn]: Failed to resolve component: EmailLayout
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
Filestructuur:
email - layout
<template>
<EHtml :lang="lang">
<slot />
</EHtml>
</template>
<script lang="ts" setup>
import { defineComponent } from 'vue';
import { EHtml } from 'vue-email';
export default defineComponent({
name: 'EmailLayout',
props: {
lang: {
type: String,
default: 'en',
},
},
})
</script>
email - template
<template>
<EmailLayout>
<e-button :href="url">View on GitHub</e-button>
</EmailLayout>
</template>
<script lang="ts" setup>
defineProps<{ url: string }>();
</script>
If you're doing the parsing yourself, then this should be an easy enough import to strip from the file.
If import starts with import type ....
Clicking a button on my UI invokes
const handleSend = async () => {
const mail = await useFetch('/api/send-email', {
method: 'POST'
})
}`
which reaches the api route of
// server/api/send-email.post.ts
import {useCompiler} from '#vue-email';
import sendgrid from '@sendgrid/mail';
sendgrid.setApiKey(process.env.SENDGRID_API_KEY || '');
export default defineEventHandler(async (event) => {
const template = await useCompiler('welcome.vue', {
url: 'https://vuemail.net/',
})
const options = {
from: '[email protected]',
to: '[email protected]',
subject: 'hello world',
html: template,
};
await sendgrid.send(options);
return { message: 'Email sent' };
});
, and returns an error code of 500 with explanation
[nuxt] [request error] [unhandled] [500] 'import' statement of ES modules is not supported
Use asynchronous function 'importFromString' instead or replace it with dynamic 'import()' expression.
at importFromStringSync (/C:/Users/deniz/Documents/Code/nuxtcv/node_modules/module-from-string/dist/index.mjs:247:13) 20:30:54
at templateRender (/C:/Users/deniz/Documents/Code/nuxtcv/.nuxt/dev/index.mjs:19215:21)
at useCompiler (/C:/Users/deniz/Documents/Code/nuxtcv/.nuxt/dev/index.mjs:19293:26)
at async /C:/Users/deniz/Documents/Code/nuxtcv/.nuxt/dev/index.mjs:19309:20
at async Object.handler (/C:/Users/deniz/Documents/Code/nuxtcv/node_modules/h3/dist/index.mjs:1683:19)
at async Server.toNodeHandle (/C:/Users/deniz/Documents/Code/nuxtcv/node_modules/h3/dist/index.mjs:1893:7)
Other api routes work just fine.
Within the docs it is showing how to import the button
hi,
i can't set the textTransform: "uppercase" in button, it seems this is the reason here in file https://github.com/Dave136/vue-email/blob/main/src/components/EButton.ts
const buttonTextStyle = computed(() => ({
...styles,
maxWidth: '100%',
display: 'inline-block',
lineHeight: '120%',
textDecoration: 'none',
textTransform: 'none',
msoPaddingAlt: '0px',
msoTextRaise: pxToPt(py.toString()),
}))
i think it should be like this
const buttonTextStyle = computed(() => ({
maxWidth: '100%',
display: 'inline-block',
lineHeight: '120%',
textDecoration: 'none',
textTransform: 'none',
msoPaddingAlt: '0px',
msoTextRaise: pxToPt(py.toString()),
...styles,
}))
Reproduction:
Repo: https://github.com/birdlavv/vue-email-reproduction
Vercel deploy: https://vue-email-repro.vercel.app/api/test
The reproduction was made by
vue-email
WelcomeEmail.vue
/api/test.ts
export default defineEventHandler(async (event) => {
const template = await useCompiler('WelcomeEmail.vue')
return template
})
Any assistance/insight into what is causing this would be greatly appreciated.
Possible related issues:
Hi,
Seems like there is a bug when using Tailwind with Font Awesome.
When i am using Tailwind no Font Awesome icon gets displayed.
But when i move the icon out of the block it works.
Wont be displayed:
<ETailwind>
<!-- some code -->
<span class="fa-solid fa-house"></span>
</ETailwind>
Gets displayed:
<ETailwind>
<!-- some code -->
</ETailwind>
<span class="fa-solid fa-house"></span>
Hi,
I'm building a drag and drop builder for vuemail.
I'm using json and dynamic components for this.
Proof of concept is working, but I need some mechanism to render the current displayed email.
How can I achieve this?
Regards
I want to use this library to compile the vue templates in a Deno environment. The only thing that stops me from doing that ist the isomorphic-dompurify library. The lib calls to the node vm api which is/will not be supported in Deno.
I did a little digging and found out you guys are just using the Library for Sanitizing, is there another Library you could use for that? Like sanitize-html
Or is there something that would speak against that?
I would like to contribute if we come to an agreement.
Hey!
Would Brevo be on your list to integrate with Vue email?
https://www.npmjs.com/package/@getbrevo/brevo
Cheers,
Ben
Hey folks,
Not sure how, but it would be awesome if you guys were able to render and send emails for this library with Laravel. As currently the "out of the box" email system is super iffy.
Not sure how it would be done, but it would please many people
hi,
i use daisyui in my app, i want email to have same look as app, is there a way to add daisyui to tailwind ? i tried to add it but getting there errors, may be i am doing some thing wrong !
my config
const tailwindConfig = {
plugins: [require("daisyui")],
theme: {
extend: {
colors: {
primary: "#007291",
},
},
},
daisyui: {
themes: ["winter"],
},
}
errors
[Vue warn]: Unhandled error during execution of setup function
at <ETailwind config= {
plugins: [ { handler: [Function: mainFunction], config: [Object] } ],
theme: { extend: { colors: [Object] } },
daisyui: { themes: [ 'winter' ] }
} >
file:///F:/node-local/vue-email-maker/node_modules/vue-email/dist/shared/vue-email.0984d17f.mjs:3684
throw new Error("Tailwind: To use responsive styles you must have a <html> and <head> element in your template.");
^
Error: Tailwind: To use responsive styles you must have a <html> and <head> element in your template.
at setup (file:///F:/node-local/vue-email-maker/node_modules/vue-email/dist/shared/vue-email.0984d17f.mjs:3684:13)
Node.js v18.17.1
We noticed today that a fix for a breaking issue is missing from the published NPM package in 0.8.0-beta.5
.
The code change that appears to be missing can be seen here and in the screenshots below: f412221
We had hoped to use this release to fix issues that we are experiencing in production on iOS devices caused by this regex issue.
Please let us know if we can assist in republishing the changes.
Hello,
are there plans to support https://amp.dev/about/email?
Hey,
When attempting to import the 'vue-email/compiler' into my SSR-enabled backend project, I encountered an error. It seems that the library may not be fully compatible with the older project's setup (typescript in common.js mode). The specific error message I received is
"Cannot find module 'vue-email/compiler' or its corresponding type declarations.ts(2307)"
Some of my tsconfig.json :
"target": "es2017",
"module": "CommonJS",
"strict": true,
"noImplicitAny": false,
"experimentalDecorators": true,
"esModuleInterop": true,
"emitDecoratorMetadata": true,
Is there an alternate way I can import the compiler in CommonJS module?
It would be nice if other imports would be allowed too. I already have a tailwind config in the project, and if possible I don't want to duplicate it. (currently I'm importing it in the script and passing it as a prop) Or perhaps use a composable and in nuxt the useRuntimeConfig()
Originally posted by @nandi95 in #64 (comment)
TODO:
Hi @Dave136,
I can't seem to get the package to work in a Nuxt repo.
Looks like deepmerge isn't providing an es module for html-to-text:
Uncaught SyntaxError: The requested module '/_nuxt/node_modules/.pnpm/[email protected]/node_modules/deepmerge/dist/cjs.js?v=74dcc2a2' does not provide an export named 'default' (at html-to-text.mjs?v=74dcc2a2:4:8)
Repro
Clone this repo, copy vue-email/playgrounds/nuxt into its own project, remove the aliasing to vue-email and run the project.
emails folder is expected to be at the top level.
I have all files in a src
directory. and I set the srcDir to the same.
https://nuxt.com/docs/api/configuration/nuxt-config#srcdir
Hey there, I am looking for a project just like this however from the documentation it appears like I can only render the vue templates within a browser, is this the case?
Happy to contribute some examples if its not
Thanks!
We are using this on a live project. Great jobs guys
After install and minimal e-mail template created I tried to see it in the Devtools, but the panel opens 404 (in my project) or welcome page in Nuxt quickstart template.
For some reason the peer dependency for vue
is locked to 3.3.4
, this is breaking the builds.
The dependency should be ^3.3.4
It looks like nested components classes are not transformed to inline style.
I have a base component which will be the base for all my emails. It include the ETailwind
component.
// BaseEmail.vue
<template>
<ETailwind :config="tailwindConfig">
<slot />
<EText class="text-accent text-center">BaseEmail Component</EText>
<MyFooter />
</ETailwind>
<template>
<script setup lang="ts">
import tailwindConfig from "~/tailwind.config";
</script>
// MyEmail.vue
<template>
<BaseEmail>
<EText class="text-accent text-center">MyEmail Component</EText>
</BaseEmail>
</template>
// MyFooter.vue
<template>
<EText class="text-accent text-center">Footer Component</EText>
</template>
Classes from BaseEmail.vue
and MyEmail.vue
are correctly transformed into inline style but classes from MyFooter.vue
are not.
This is what useRender
returns for the 3 EText
:
<p data-id="__vue-email-text" style="font-size:14px;line-height:24px;margin:16px 0;color:rgb(129,53,255);text-align:center;">MyEmail Component</p>
<p data-id="__vue-email-text" style="font-size:14px;line-height:24px;margin:16px 0;color:rgb(129,53,255);text-align:center;">BaseEmail Component</p>
<p data-id="__vue-email-text" style="font-size:14px;line-height:24px;margin:16px 0;" class="text-accent text-center">Footer Component</p>
I made a reproduction repository here : repo
Hi, I think this is problem of the new compiler, since this didn't happen before.
Here is example template:
<template>
<e-html>
<e-head />
<e-preview>Preview</e-preview>
<e-tailwind>
<e-body class="mx-auto my-auto bg-white font-sans">
<e-container
class="mx-auto my-[40px] w-[465px] rounded border border-solid border-[#eaeaea] p-[20px]"
>
<e-section>
<e-text class="text-[12px] leading-[24px] text-[#666666]">
new line
</e-text>
<e-text class="text-[12px] leading-[24px] text-[#666666]">
new line
<br>
new line
<br>
new line
<br>
new line
<br>
new line
<br>
new line
</e-text>
</e-section>
</e-container>
</e-body>
</e-tailwind>
</e-html>
</template>
<script lang="ts" setup>
//
</script>
The <br> element gets duplicated at the end of the section thus adding blank white space.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.