├── assets
└── styles.css
├── .babelrc
├── .gitignore
├── src
├── cli.js
├── server.js
├── email-second.js
└── email.js
├── README.md
├── package.json
└── LICENSE
/assets/styles.css:
--------------------------------------------------------------------------------
1 | .red {
2 | color: red;
3 | }
4 |
5 | .blue {
6 | color: blue;
7 | }
8 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/preset-react",
4 | "@babel/preset-env"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 | *npm-debug.log
4 | package-lock.json
5 | .history
6 | .idea
7 | *.iml
8 | .DS_Store
9 |
--------------------------------------------------------------------------------
/src/cli.js:
--------------------------------------------------------------------------------
1 | import { render } from 'mjml-react';
2 |
3 | import { generate } from './email';
4 |
5 | const { html } = render(generate(), { validationLevel: 'soft' });
6 | console.log(html);
7 |
--------------------------------------------------------------------------------
/src/server.js:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import {render} from 'mjml-react';
3 |
4 | import * as email1 from './email';
5 | import * as email2 from './email-second';
6 |
7 | const port = 3000;
8 | const app = express();
9 |
10 | app.get('/2', (req, res) => {
11 | const {html} = render(email2.generate(), {validationLevel: 'soft'});
12 | res.send(html);
13 | });
14 |
15 | app.get('*', (req, res) => {
16 | const {html} = render(email1.generate(), {validationLevel: 'soft'});
17 | res.send(html);
18 | });
19 |
20 | app.listen(port, () => console.log(`Listening on port ${port}!`));
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # mjml-react example project
2 |
3 | The aim of this project is to show usage of [mjml](https://mjml.io/) and [mjml-react](https://github.com/wix-incubator/mjml-react) inside a node js.
4 |
5 | ## Usage
6 |
7 | ```bash
8 | git clone git@github.com:wix-incubator/mjml-react-example.git
9 | cd mjml-react-example
10 | npm install
11 | npm start
12 | ```
13 |
14 | and afterwards just open your browser using the link [http://localhost:3000/](http://localhost:3000/).
15 |
16 | > The http server will listen and restart upon each change inside src folder.
17 | > You just need to refresh a browser window manually.
18 |
19 | ### Running from command line
20 |
21 | You can also run and get your email inside console:
22 |
23 | ```bash
24 | npm run build
25 | npm run generate
26 | ```
27 |
28 | And you can automate things by sending the generated email to your test inbox:
29 |
30 | ```bash
31 | npm run build
32 | npm run generate | mail -s "$(echo -e "This is a test email\nContent-Type: text/html")" myemail@myprovider.com
33 | ```
34 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mjml-react-example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "babel src --out-dir dist",
8 | "build:watch": "babel src --out-dir dist --watch",
9 | "prestart": "npm run build",
10 | "start": "npm run build:watch & nodemon ./dist/server.js --watch ./dist",
11 | "generate": "node ./dist/cli.js"
12 | },
13 | "author": {
14 | "name": "Mantas Miliukas",
15 | "email": "mantasm@wix.com"
16 | },
17 | "homepage": "https://github.com/wix-incubator/mjml-react-example",
18 | "bugs": "https://github.com/wix-incubator/mjml-react-example/issues",
19 | "license": "MIT",
20 | "devDependencies": {
21 | "@babel/cli": "^7.2.3",
22 | "@babel/core": "^7.2.2",
23 | "@babel/preset-env": "^7.3.1",
24 | "@babel/preset-react": "^7.0.0"
25 | },
26 | "dependencies": {
27 | "express": "^4.16.4",
28 | "mjml": "^4.3.1",
29 | "mjml-react": "^1.0.45",
30 | "nodemon": "^1.18.9",
31 | "react": "^16.7.0",
32 | "react-dom": "^16.7.0"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Wix.com
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/src/email-second.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { readFileSync } from 'fs';
3 |
4 | import {
5 | Mjml,
6 | MjmlHead,
7 | MjmlTitle,
8 | MjmlPreview,
9 | MjmlBody,
10 | MjmlSection,
11 | MjmlColumn,
12 | MjmlButton,
13 | MjmlImage,
14 | MjmlStyle,
15 | MjmlText
16 | } from 'mjml-react';
17 |
18 | export const generate = () => {
19 | return (
20 |
21 |
22 | Last Minute Offer
23 | Last Minute Offer...
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | This Yet Another Template
35 |
36 |
37 |
38 |
39 |
40 | Go Back
41 |
42 |
43 |
44 |
45 | );
46 | };
47 |
--------------------------------------------------------------------------------
/src/email.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { readFileSync } from 'fs';
3 |
4 | import {
5 | Mjml,
6 | MjmlHead,
7 | MjmlTitle,
8 | MjmlPreview,
9 | MjmlBody,
10 | MjmlSection,
11 | MjmlColumn,
12 | MjmlButton,
13 | MjmlImage,
14 | MjmlStyle,
15 | MjmlText
16 | } from 'mjml-react';
17 |
18 | const css = readFileSync('./assets/styles.css').toString();
19 |
20 | export const generate = () => {
21 | return (
22 |
23 |
24 | Last Minute Offer
25 | Last Minute Offer...
26 | {css}
27 | {`
28 | .blue-column {
29 | background-color: blue;
30 | }
31 | `}
32 | {`
33 | .red-column {
34 | background-color: red;
35 | }
36 | `}
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | I like it!
48 |
49 |
50 |
51 |
52 |
53 | I am blue
54 |
55 |
56 | I am red
57 |
58 |
59 |
60 |
61 | Open Second Template
62 |
63 |
64 |
65 |
66 | );
67 | };
68 |
--------------------------------------------------------------------------------