vue-email-editor icon indicating copy to clipboard operation
vue-email-editor copied to clipboard

Vue 3 not supported.

Open alihankoc opened this issue 3 years ago • 24 comments

Can you please add vue 3 support?

alihankoc avatar Jan 29 '22 12:01 alihankoc

https://github.com/Tofandel/vue-unlayer

Much cleaner, vue 3 only

Tofandel avatar Mar 15 '22 17:03 Tofandel

@Tofandel can't get your package to work Can't resolve '@tofandel/vue-unlayer' when importing

RyonMB avatar May 09 '22 19:05 RyonMB

@Tofandel Poorly the package is not installable.

abcmoritz avatar May 29 '22 17:05 abcmoritz

Forgot to publish it, now it's good

Tofandel avatar May 31 '22 21:05 Tofandel

When installing Remove :appearance="appearance" as it is throwing an error Uncaught DOMException: Failed to execute 'postMessage' on 'Window': #<Object> could not be cloned.

Use this instead

<EmailEditor
        v-model:editor="editor"
        :min-height="minHeight"
        :project-id="projectId"
        :locale="locale"
        :tools="tools"
        :options="options"
        @load="editorLoaded"
        @ready="editorReady"
      />

ekpono avatar Jul 20 '22 13:07 ekpono

When installing Remove :appearance="appearance" as it is throwing an error Uncaught DOMException: Failed to execute 'postMessage' on 'Window': #<Object> could not be cloned.

Use this instead

<EmailEditor
        v-model:editor="editor"
        :min-height="minHeight"
        :project-id="projectId"
        :locale="locale"
        :tools="tools"
        :options="options"
        @load="editorLoaded"
        @ready="editorReady"
      />

I get this error when I try to use this in Nuxt 3.. If I try to call a function I get Uncaught DOMException: Failed to execute 'postMessage' on 'Window': #<Object> could not be cloned.

Any suggestions?

BayBreezy avatar Jan 29 '23 19:01 BayBreezy

@BayBreezy

I get the same error when I use

const editor = ref(null);

for the v-model. If I use

const editor = shallowRef(null);

the error disappears.

9uenther avatar Apr 03 '23 23:04 9uenther

@BayBreezy

I get the same error when I use

const editor = ref(null);

for the v-model. If I use

const editor = shallowRef(null);

the error disappears.

Are you able to navigate away from the page and back without getting an error? If I navigate to a different page and then go back to the editor, I get the error

BayBreezy avatar Apr 04 '23 00:04 BayBreezy

I use it inside ClientOnly tag:

<ClientOnly>
    <div class="w-full">
        <EmailEditor
            :appearance="{theme: 'dark'}"
            v-model:editor="editor"
            @load="editorLoaded"
            @ready="editorReady"
        />
    </div>
</ClientOnly>

But I have another navigation issue when I navigate away and back. I get following error, and the editor isn't loading:

Uncaught (in promise) Error: Could not find a valid element for given id or className.          embed.js:1
    at e.value (embed.js:1:19690)
    at e.value (embed.js:1:18944)
    at new e (embed.js:1:18797)
    at s.value (embed.js:1:30819)
    at EmailEditor.vue:48:27
    at loadScript (loadScript.js:24:5)
    at setup (EmailEditor.vue:39:1)
    at callWithErrorHandling (chunk-BAAL4GTK.js?v=9f166373:1722:1)
    at setupStatefulComponent (chunk-BAAL4GTK.js?v=9f166373:6617:1)
    at setupComponent (chunk-BAAL4GTK.js?v=9f166373:6580:1)

9uenther avatar Apr 04 '23 06:04 9uenther

I found a fix.. just assign an editorId to the component... @9uenther

BayBreezy avatar Apr 04 '23 15:04 BayBreezy

I switch back to basics

const editor = ref(null);

const editorSave = () => {
    console.log(editor.value.html);
};

watch(editor, (val, oldVal) => {
    console.log('unlayer-editor', val);
}, {deep: true})

onMounted(() => {

    if(process.client && !document.getElementById('unlayer-embed')) {
        const s = document.createElement('script');
        s.src = '//editor.unlayer.com/embed.js';
        s.id = 'unlayer-embed';
        s.type = 'text/javascript';
        s.async = true;
        s.addEventListener('load', () => {

            const e = unlayer.createEditor({
                options: {},
                appearance: {
                    theme: 'dark'
                },
                id: 'unlayer-editor',
                displayMode: 'email'
            })

            e.addEventListener('design:updated', () => {
                e.exportHtml((ctx) => {
                    editor.value = {...ctx}
                });
            });
        }, false)

        document.body.appendChild(s);
    }
});

it works fine in my environment. Even if I navigate back and forth.

9uenther avatar Apr 04 '23 15:04 9uenther

I found a fix.. just assign an editorId to the component... @9uenther

At which location does something have to be inserted? Do you have an example code?

9uenther avatar Apr 04 '23 15:04 9uenther

Will re-create a repo and share it soon

BayBreezy avatar Apr 04 '23 15:04 BayBreezy

Any updates @BayBreezy ?

Jensxy avatar Apr 26 '23 19:04 Jensxy

Hey @Jensxy

 <EmailEditor
        :options="options"
        :appearance="appearance"
        minHeight="100%"
        style="height: 100%"
        editorId="1"
        ref="emailEditorRef"
/>

The entire file that i have is below

Click to view
<template>
  <div>
    <header class="border-b dark:border-gray-800/50">
      <div class="mx-auto flex h-16 max-w-7xl items-center justify-between px-5">
        <NuxtLink class="font-bold" to="/">Designer</NuxtLink>
        <div class="flex items-center justify-center gap-5">
          <button @click="hiddenPicker.click()" class="btn text-xs">Import Design</button>
          <button @click="saveDesign()" class="btn text-xs">Save Design</button>
          <button @click="exportHtml()" class="btn text-xs">Export Design</button>
        </div>
      </div>
    </header>
    <main class="h-[calc(100vh-65px)]">
      <EmailEditor
        :options="options"
        :appearance="appearance"
        minHeight="100%"
        style="height: 100%"
        editorId="1"
        ref="emailEditorRef"
      />
    </main>
    <input
      type="file"
      ref="hiddenPicker"
      hidden
      accept=".json"
      @change="importDesign"
      @click="clearInput"
    />
  </div>
</template>

<script setup lang="ts">
//@ts-ignore
import { EmailEditor } from "vue-email-editor";
import colors from "tailwindcss/colors";
import { ExportHtml, SaveDesign } from "~/types";

// ref of the email editor
const emailEditorRef = ref();
// ref of hiiden input
const hiddenPicker = ref();

const { isDark } = useTheme();

// Method used to save a design
function saveDesign() {
  emailEditorRef.value?.editor.saveDesign((design: SaveDesign) => {
    console.log("saveDesign", design);
  });
}

// Method used to export a design
function exportHtml() {
  emailEditorRef.value?.editor.exportHtml((data: ExportHtml) => {
    console.log("exportHtml", data);
  });
}

// Method used to import a design
function importDesign() {
  const file = hiddenPicker.value.files[0];
  if (!file) return;
  if (file.type !== "application/json") return;
  const reader = new FileReader();
  reader.onload = (e) => {
    const result = e.target?.result;
    if (result) {
      emailEditorRef.value?.editor.loadDesign(JSON.parse(result.toString()));
    }
  };
  reader.readAsText(file);
}

// Method used to clear the input
function clearInput() {
  hiddenPicker.value.value = "";
}

const options = {
  fonts: {
    showDefaultFonts: false,
  },
  features: {
    colorPicker: {
      presets: [
        "#fff",
        "#000",
        colors.gray[700],
        colors.teal[500],
        colors.red[500],
        colors.yellow[500],
        colors.green[500],
        colors.blue[500],
        colors.indigo[500],
        colors.purple[500],
        colors.pink[500],
      ],
    },
  },
};

const appearance = computed(() => {
  return {
    theme: isDark ? "dark" : "light",
  };
});
</script>

BayBreezy avatar Apr 29 '23 05:04 BayBreezy

I am running into this issue as well when using with Nuxt 3. I am also getting weird 502 errors with the API call that is made from within the library to https://api.events.unlayer.com/usage. Is this library still actively supported? Appears there are multiple open issues getting little to no attention

AmareshKulkarni avatar Oct 12 '23 19:10 AmareshKulkarni

Hello @AmareshKulkarni , I got this workign in Nuxt 3. You can check out the repo here: https://github.com/BayBreezy/templates. This is a link to the live website: https://templates.behonbaker.com/

Check this file to see how I got the editor to work: https://github.com/BayBreezy/templates/blob/main/pages/editor.vue

BayBreezy avatar Oct 13 '23 00:10 BayBreezy

Hello @AmareshKulkarni , I got this workign in Nuxt 3. You can check out the repo here: BayBreezy/templates. This is a link to the live website: templates.behonbaker.com

Check this file to see how I got the editor to work: BayBreezy/templates@main/pages/editor.vue

@BayBreezy Thank you so much for the reference provided. Though my issue is not resolved, It did help me narrow down the problem, t appears if I directly navigate to the page using http://localhost:3000/editor it works fine. However if I navigate to that route by clicking on a link, it doesn't seem to work.Not sure what the issue is but definitely helps zoom in on the routing issue. It could be something to do with my routing logic. The error message really throwing me off.

AmareshKulkarni avatar Oct 13 '23 23:10 AmareshKulkarni

@AmareshKulkarni I had that same issue at one point. The key was to set the editorId value to 1 if the ID from the loaded design is undefined

BayBreezy avatar Oct 13 '23 23:10 BayBreezy

@AmareshKulkarni I had that same issue at one point. The key was to set the editorId value to 1 if the ID from the loaded design is undefined

In my case, I literally copied the relevant parts of editor.vue, which had the editorId, but I still get that error. I am able to produce the issue with routing. I will post what I find.

AmareshKulkarni avatar Oct 13 '23 23:10 AmareshKulkarni

@AmareshKulkarni ooohhh.. dang.. well, let me know what you come up with

BayBreezy avatar Oct 13 '23 23:10 BayBreezy

@AmareshKulkarni ooohhh.. dang.. well, let me know what you come up with

Also the other thing is the APIs that get called in a successful scenario,

https://api.unlayer.com/v2/editor/auth https://api.unlayer.com/v2/editor/session

don't get called when I run in to error. I wonder if there are any fetch related issues because my application is already using fetch and if there is a conflict somehow.

I confirm it is also not related to routing logic, because I tried with navigateTo({name:'editor'}) in the code base that you shared, and it was working flawlessly.

When it fails, here is the dom tree that I see:

<div class="h-[calc(100dvh-65px)]" data-v-inspector="components/EmailEditorWrapper.vue:52:3"><div data-v-eb864766="" id="1" class="unlayer-editor" style="min-height: 500px; height: 100%;"></div></div>

AmareshKulkarni avatar Oct 13 '23 23:10 AmareshKulkarni

Very strange issue that I can not explain why, but here is what was happening... I had transitions enabled in my Nuxt app globally.. So, when I was transitioning from page to page, the issue - " Could not find a valid element for given id or className. " was showing up. I was not running into this issue when I was directly navigating to a page with Editor, as the transitions were not kicking in.

I disabled transitions, the editor was successfully loaded. It worked without the editorId being passed. I will have to see if there is a way to disable transition for this one page.

I still have errors in my console for 502 errors:

`Access to fetch at 'https://api.events.unlayer.com/save' from origin 'https://editor.unlayer.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. editor.js:2

   POST https://api.events.unlayer.com/save net::ERR_FAILED 502 (Bad Gateway)

(anonymous) @ editor.js:2 d @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 kn @ editor.js:2 a @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 En @ editor.js:2 Sn @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 rt @ editor.js:2 (anonymous) @ editor.js:2 c @ editor.js:2 (anonymous) @ editor.js:2 d @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 R @ editor.js:2 a @ editor.js:2 Promise.then (async) R @ editor.js:2 a @ editor.js:2 Promise.then (async) R @ editor.js:2 a @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 ze @ editor.js:2 (anonymous) @ editor.js:2 d @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 oe @ editor.js:2 a @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 setTimeout (async) value @ editor.js:2 value @ editor.js:2 (anonymous) @ editor.js:2 editor.js:2

   Uncaught (in promise) TypeError: Failed to fetch
at editor.js:2:1625907
at d (editor.js:2:1618497)
at Generator.<anonymous> (editor.js:2:1619825)
at Generator.next (editor.js:2:1618907)
at kn (editor.js:2:1625410)
at a (editor.js:2:1625614)
at editor.js:2:1625675
at new Promise (<anonymous>)
at Module.<anonymous> (editor.js:2:1625554)
at Module.En (editor.js:2:1626132)`

AmareshKulkarni avatar Oct 14 '23 01:10 AmareshKulkarni

Very strange issue that I can not explain why, but here is what was happening... I had transitions enabled in my Nuxt app globally.. So, when I was transitioning from page to page, the issue - " Could not find a valid element for given id or className. " was showing up. I was not running into this issue when I was directly navigating to a page with Editor, as the transitions were not kicking in.

I disabled transitions, the editor was successfully loaded. It worked without the editorId being passed. I will have to see if there is a way to disable transition for this one page.

I still have errors in my console for 502 errors:

`Access to fetch at 'https://api.events.unlayer.com/save' from origin 'https://editor.unlayer.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. editor.js:2

   POST https://api.events.unlayer.com/save net::ERR_FAILED 502 (Bad Gateway)

(anonymous) @ editor.js:2 d @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 kn @ editor.js:2 a @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 En @ editor.js:2 Sn @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 rt @ editor.js:2 (anonymous) @ editor.js:2 c @ editor.js:2 (anonymous) @ editor.js:2 d @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 R @ editor.js:2 a @ editor.js:2 Promise.then (async) R @ editor.js:2 a @ editor.js:2 Promise.then (async) R @ editor.js:2 a @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 ze @ editor.js:2 (anonymous) @ editor.js:2 d @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 oe @ editor.js:2 a @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 (anonymous) @ editor.js:2 setTimeout (async) value @ editor.js:2 value @ editor.js:2 (anonymous) @ editor.js:2 editor.js:2

   Uncaught (in promise) TypeError: Failed to fetch
at editor.js:2:1625907
at d (editor.js:2:1618497)
at Generator.<anonymous> (editor.js:2:1619825)
at Generator.next (editor.js:2:1618907)
at kn (editor.js:2:1625410)
at a (editor.js:2:1625614)
at editor.js:2:1625675
at new Promise (<anonymous>)
at Module.<anonymous> (editor.js:2:1625554)
at Module.En (editor.js:2:1626132)`

Finally it was fixed today.

mrcego avatar Mar 06 '24 21:03 mrcego