以下の記事で、HTMLメールエディターの存在を知りました。
SaaSのサービス開発で、メールの送信機能を実装することがあるかもしれませんが
メールエディタまで自前で作るとなると大変なのかなと思います。
以下のページに行くと、
The Embeddable Drag & Drop Email Editor and Page Builder for SaaS
こちらは、React/Vue/Angular用が用意されています。
早速ローカルで、動かすところまでやってみたいと思います。
目次
vue-email-editorを動かしてみる
前提
- Mac環境
- Nodeのコマンドがインストール済みであること
- vue-cliを利用して動かす
動作確認できるサンプル
vue-cliのインストール
ターミナルを起動して、以下を実行します。
$ npm install -g @vue/cli
適当なディレクトリを作成し、プロジェクトを作成します。
$ mkdir sample
$ cd sample
$ vue create email-editor
ディレクトリを移動して、以下のコマンドを実行します。
$ cd email-editor
$ npm run serve
以下のように表示されるので、http://localhost:8081/にアクセスします。
(環境によっては、8081の部分が、8080)
以下のようなページが表示されたら準備完了です。
vue-email-editorのインストール
vue-email-editorをnpmでインストールします。(アプリケーションの実行に必要なものなので、–save)
$ pwd
$ email-editor
$ npm install vue-email-editor --save
App.vueの中身を差し替えます。
$ cd src
$ cp App.vue App.vue.20210124
$ vim App.vue
以下の内容に差し替えます。
<template>
<div id="app">
<div class="container">
<div id="bar">
<h1>Vue Email Editor (Demo)</h1>
<button v-on:click="saveDesign">Save Design</button>
<button v-on:click="exportHtml">Export HTML</button>
</div>
<EmailEditor ref="emailEditor" v-on:load="editorLoaded" />
</div>
</div>
</template>
<script>
import { EmailEditor } from 'vue-email-editor'
export default {
name: 'app',
components: {
EmailEditor
},
methods: {
editorLoaded() {
this.$refs.emailEditor.editor.loadDesign({});
},
saveDesign() {
this.$refs.emailEditor.editor.saveDesign(
(design) => {
console.log('saveDesign', design);
}
)
},
exportHtml() {
this.$refs.emailEditor.editor.exportHtml(
(data) => {
console.log('exportHtml', data);
}
)
}
}
}
</script>
差し替えるとnpm run serveが動作しているのでページが更新されます。
思った表示になっていません。
DevToolsを開くと、以下のjsエラーが確認できます。
これは、このエディタの中でつかっている、editor.js内でのエラーのようです。
editor.js:101 TypeError: Cannot read property 'location' of undefined
at Function.mapToProps (editor.js:155)
at r (editor.js:14)
at Function.r.mapToProps (editor.js:14)
at r (editor.js:14)
at editor.js:14
at editor.js:14
at Object.useMemo (editor.js:101)
at t.useMemo (editor.js:93)
at O (editor.js:14)
at Yi (editor.js:101)
TypeError: Cannot read property 'values' of undefined
at editor.js:155
at Yi (editor.js:101)
at Na (editor.js:101)
at Da (editor.js:101)
at Ra (editor.js:101)
at bl (editor.js:101)
at cs (editor.js:101)
at ls (editor.js:101)
at Ql (editor.js:101)
at editor.js:101
Uncaught (in promise) TypeError: Cannot read property 'location' of undefined
at Function.mapToProps (editor.js:155)
at r (editor.js:14)
at Function.r.mapToProps (editor.js:14)
at r (editor.js:14)
at editor.js:14
at editor.js:14
at Object.useMemo (editor.js:101)
at t.useMemo (editor.js:93)
at O (editor.js:14)
at Yi (editor.js:101)
エラー内容で検索をかけてみると以下のページにたどり着きます。
App.vue内のmethodsのeditorLoadedを以下に変更します。
editorLoaded() {
this.$refs.emailEditor.editor.loadDesign({"counters":{"u_column":1,"u_row":1},"body":{"rows":[{"cells":[1],"columns":[{"contents":[],"values":{"backgroundColor":"","padding":"0px","border":{},"_meta":{"htmlID":"u_column_1","htmlClassNames":"u_column"}}}],"values":{"displayCondition":null,"columns":false,"backgroundColor":"","columnsBackgroundColor":"","backgroundImage":{"url":"","fullWidth":true,"repeat":false,"center":true,"cover":false},"padding":"0px","hideDesktop":false,"hideMobile":false,"noStackMobile":false,"_meta":{"htmlID":"u_row_1","htmlClassNames":"u_row"},"selectable":true,"draggable":true,"duplicatable":true,"deletable":true}}],"values":{"backgroundColor":"#e7e7e7","backgroundImage":{"url":"","fullWidth":true,"repeat":false,"center":true,"cover":false},"contentWidth":"500px","fontFamily":{"label":"Arial","value":"arial,helvetica,sans-serif"},"preheaderText":"","linkStyle":{"body":true,"linkColor":"#0000ee","linkHoverColor":"#0000ee","linkUnderline":true,"linkHoverUnderline":true},"_meta":{"htmlID":"u_body","htmlClassNames":"u_body"}}},"schemaVersion":5});
}
エディタの部分が表示されました。しかし、高さがありません。
App.vueに、以下のcssを追加します。
<style>
.unlayer-editor {
height: 600px;
}
</style>
以下のようにエディタが正しく表示されました。
Save Design、Export Htmlの確認
こちらは、App.vueを確認すると以下の実装になっているので、DevToolsのconsoleに出力されます。
saveDesign() {
this.$refs.emailEditor.editor.saveDesign(
(design) => {
console.log('saveDesign', design);
}
)
},
exportHtml() {
this.$refs.emailEditor.editor.exportHtml(
(data) => {
console.log('exportHtml', data);
}
)
}
これだけでも、ローカルで動作するメールエディタとしては十分です。
exportHtmlを以下のようにしておけば、htmlだけ確認できます。
exportHtml() {
this.$refs.emailEditor.editor.exportHtml(
(data) => {
console.log(data.html);
}
)
}
こんな感じで、htmlがconsoleに出力されます。
便利かなと思います。
使ってみてください。
サーバ側で動かしてみる
ローカル環境と途中までは同じです。
ターミナルを起動して、以下を実行します。(vue/cliが入っていることが前提となります)
適当なディレクトリを作成し、プロジェクトを作成します。
$ mkdir sample
$ cd sample
$ vue create email-editor
Vue 2のままで実行しました。
Vue CLI v4.5.13
? Please pick a preset: (Use arrow keys)
❯ Default ([Vue 2] babel, eslint)
Default (Vue 3) ([Vue 3] babel, eslint)
Manually select features
ディレクトリを移動して、以下のコマンドを実行します。
$ cd email-editor
vue-email-editorをnpmでインストールします。
$ pwd
$ email-editor
$ npm install vue-email-editor --save
App.vueの中身を差し替えます。
$ cd src
$ cp App.vue App.vue.20210124
$ vim App.vue
以下の内容に差し替えます。
<template>
<div id="app">
<div class="container">
<div id="bar">
<h1>Vue Email Editor (Demo)</h1>
<button v-on:click="saveDesign">Save Design</button>
<button v-on:click="exportHtml">Export HTML</button>
</div>
<EmailEditor
:appearance="appearance"
:min-height="minHeight"
:project-id="projectId"
:locale="locale"
:tools="tools"
:options="options"
ref="emailEditor"
v-on:load="editorLoaded"
/>
</div>
</div>
</template>
<script>
import { EmailEditor } from 'vue-email-editor';
export default {
name: 'app',
components: {
EmailEditor,
},
data() {
return {
minHeight: '1000px',
locale: 'en',
projectId: 0, // replace with your project id
tools: {
// disable image tool
image: {
enabled: true,
},
},
options: {},
appearance: {
theme: 'dark',
panels: {
tools: {
dock: 'right',
},
},
},
};
},
methods: {
editorLoaded() {
// Pass your template JSON here
// this.$refs.emailEditor.editor.loadDesign({});
},
saveDesign() {
this.$refs.emailEditor.editor.saveDesign((design) => {
console.log('saveDesign', design);
});
},
exportHtml() {
this.$refs.emailEditor.editor.exportHtml((data) => {
console.log('exportHtml', data);
});
},
},
};
</script>
ここまでは、Macとやる方法と同じですが、WebサーバLightSpeed上で動かすために、ソースをビルドします。
ドメイン直下に置くのではなく、任意のディレクトリ内に設置する場合は、jsの読み込みパスが相対パスになるようにします。
vue.config.jsというファイルを公開ディレクトリの直下におきます。
$ cd email-editor
$ touch vue.config.js
$ vim vue.config.js
以下の内容を反映させます。
module.exports = {
publicPath: './'
}
ビルドします。ビルドするとカレントディレクトリに、/distというディレクトリができます。
そこに公開用のファイルが吐き出されます。
$ npm run build
$ ls dist
favicon.ico index.html js
以下のURLで表示してみます。
Macのときと同様に高さがなく潰れています。
以下をApp.vueに追加します。
<style>
.unlayer-editor {
height: 600px;
}
</style>
実際にメール文面を作成してみるとこんな感じです。
表示しようとしたら、以下のエラーがでました。
(Vue 3だった時に発生したので、Vue 2で作り直しました。vue create email-editorの部分です。)
vue-email-editor.common.js:3100 Uncaught TypeError: Cannot read property 'component' of undefined
at vue-email-editor.common.js:3100
at Array.forEach (<anonymous>)
at Module.fb15 (vue-email-editor.common.js:3099)
at n (vue-email-editor.common.js:21)
at e.exports.014b (vue-email-editor.common.js:85)
at Object.b990 (vue-email-editor.common.js:2)
at a (bootstrap:79)
at Module.56d7 (app.fd84a34a.js:1)
at a (bootstrap:79)
at Object.0 (app.fd84a34a.js:1)