Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Use my own components #82

Closed
thomasruffier opened this issue Oct 1, 2023 · 10 comments
Closed

[Question] Use my own components #82

thomasruffier opened this issue Oct 1, 2023 · 10 comments
Labels
question question

Comments

@thomasruffier
Copy link

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?

@Flowko
Copy link
Member

Flowko commented Oct 1, 2023

the library will only auto import from components that live in the emails folder, we handle rendering vue files differently than your normal vue app

https://www.vuemail.net/getting-started/ssr#before-you-start

@Flowko Flowko added the question question label Oct 1, 2023
@Flowko Flowko changed the title [FEATURE] Use my own components [Question] Use my own components Oct 1, 2023
Copy link

L422Y commented Oct 1, 2023

Just to note, you can create a sub-directory in the emails folder and place components there, for instance I have the hierarchy:

emails/
  Email/
     Header.vue
     Layout.vue
  TestEmail.vue

And I can use the components in my TestEmail.vue by using EmailHeader and EmailLayout

If I add import statements, currently, it breaks, but if I leave out the imports, it works like a dream.

@Flowko Flowko closed this as completed Oct 1, 2023
@mklueh
Copy link

mklueh commented Dec 22, 2023

The problem is, when you want to use components of your actual application

@Flowko
Copy link
Member

Flowko commented Dec 22, 2023

@mklueh , let me explain why we have this issue in the first place. It's because of SSR (Server-Side Rendering):

The way we handle compiling the Vue files on Node or any JS runtime is different from what you're usually used to. We've developed a custom compiler to make this possible. However, we haven't found a proper way to handle compiling/handling Vue components on the server. If you do know of one, please share it with us.

Then there's Nuxt. Nuxt handles the server-side of your "Vue" app differently as well because you have no access to Vue components on the server side. Therefore, there's no way for us to identify the components you're using and how to link them together.

Our custom solution helps us:

  • Compile Vue files into a format that createApp understands.
  • To use custom components, you have to add them inside your emails components. We load these in the createApp created earlier. If we allow users to use all their components, it will cause significant delays because we'd need to compile and add all of them.

This solution works for about 80% of our users' use cases. There was no existing solution for this, but we managed to add the SSR feature because it was never planned due to the complexity involved. I understand your desire for a seamless, 'just works' experience, but Vue is structured differently from React, making achieving that a bit challenging.

Another consideration is in the case of emails. You wouldn't use components from your UI inside the app or website because most of the time, they won't display correctly in email providers. You need to create specific components that function properly on the email side as well.

I hope this helps you understand that this is beyond our control.

@L422Y
Copy link

L422Y commented Dec 23, 2023

Well said, @Flowko, there's no sense in using modern web app components in emails, as email clients still have very limited HTML and CSS support across the board, and any unsupported code is often stripped by providers like Gmail.

Creating a new set of components specifically geared towards emails is the correct route to take – i.e. inline styles and using table a LOT – this will ensure that your emails work correctly.

@Flowko
Copy link
Member

Flowko commented Dec 23, 2023

@L422Y yes tottaly, thats why we have a set of 17 components that you can use, they get converted to a support email format, so you dont have to deal with it, that takes care of most of the use cases, but yeah, we always are trying new ways to make this library better!

@mklueh
Copy link

mklueh commented Feb 24, 2024

Thanks for the clarification regarding custom components, this makes a lot of sense!

Just to note, you can create a sub-directory in the emails folder and place components there, for instance I have the hierarchy:

emails/
  Email/
     Header.vue
     Layout.vue
  TestEmail.vue

And I can use the components in my TestEmail.vue by using EmailHeader and EmailLayout

If I add import statements, currently, it breaks, but if I leave out the imports, it works like a dream.

Is this related to Nuxt only or does this also work using CLI?

@Flowko
Copy link
Member

Flowko commented Feb 24, 2024

its related to the compiler, since its the library that handles the compiling in both nuxt and js frameworks like node and others, so CLI is the same thing, cuz its using that as well, so yeah, same structure in all of them

@mklueh
Copy link

mklueh commented Feb 24, 2024

Okay, so I've tried that with the exact structure

emails/
  Email/
     BrandedHeader.vue
  MyMail.vue

BrandedHeader.vue

<script setup>
import { ESection, EText } from "vue-email";
</script>

<template>
  <e-heading as="h1">
    Some Brand Name
  </e-heading>
</template>

MyMail.vue

<script setup>
import { EButton, EHtml } from 'vue-email'
</script>

<template>
  <EHtml lang="en">

    <BrandedHeader/>

    <EButton href="https://example.com" style="color: #61dafb">
      Click me
    </EButton>
  </EHtml>
</template>

now I run the command in the root

npx vue-email export

And get the output

$ npx vue-email export
ℹ ✨ Generating HTML versions of emails                                                                                                                                                                                                                  13:01:06
[Vue warn]: Failed to resolve component: BrandedHeader
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
ℹ 🪄 Generated MyMail                                                                                                                                                                                                                                    13:01:06
ℹ 🪄 Generated Email/BrandedHeader       

And this is the generated HTML

<!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="en" dir="ltr">
<BrandedHeader></BrandedHeader>
<a data-id="__vue-email-button"
   style="line-height:100%;text-decoration:none;display:inline-block;max-width:100%;color:#61dafb;"
   href="https://example.com" target="_blank"><span><!--[if mso]><i style="letter-spacing: 0px;mso-font-width:-100%;mso-text-raise:0" hidden>&nbsp;</i><![endif]--></span><span
  style="max-width:100%;display:inline-block;line-height:120%;text-decoration:none;text-transform:none;mso-padding-alt:0px;mso-text-raise:0;"> Click me </span><span><!--[if mso]><i style="letter-spacing: 0px;mso-font-width:-100%" hidden>&nbsp;</i><![endif]--></span></a>
</html>

I've tried that also with imports, but this leads to an error.

Am I missing something like an extra config file or something like that?

@L422Y
Copy link

L422Y commented Feb 24, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question question
Projects
None yet
Development

No branches or pull requests

4 participants