mj-include won't work if .mjml file is in a subdirectory.
Reproduction Steps:
.../ like that:const fs = require("fs");
const path = require('path');
const mjml = require("mjml");
const mjMail = fs.readFileSync(path.join(__dirname, "emails", "email.mjml"), "utf8");
const htmlMail = mjml.mjml2html(mjMail);
.../emails/email.mjml in folder .../emails/:<mjml>
<mj-head> <mj-include path="./emails/common-head" /> </mj-head>
<mj-body> <mj-container> ... </mj-container> </mj-body>
</mjml>
.../emails/common-head.mjml:<mj-attributes>...</mj-attributes>
<mj-style>...</mj-style>
Expected behavior:
An HTML file will be created with the included common head file
Observed behavior:
The common head is not included and the script prints the error Warning: No handler found for: mj-raw, in mj-head, skipping it
MJML version:
v3.3.5
Changes which resolve the issue:
email.mjml in the same directory as the script and including the mjml files from a subdirectory. (also not ideal)Hey @IchordeDionysos, thanks for taking the time to investigate and describe that issue.
It looks related to https://github.com/mjmlio/mjml/issues/970 which is fixed for the next beta. We'll release a new beta version tomorrow with that fix, please let us know if it still happens then!
Waiting for new release
Same here
Any news?
Please be patient @ilyaskorik, we're working on the new beta version and will release it really soon. Also, if it's that urgent, you can git clone and install MJML locally instead of waiting for us to publish the beta release (everything you need is in the readme).
The issue was opened 4 days ago, bumping it every 18 hours won't help 馃檪.
This is now fixed in MJML 4.0.0-beta.2 so I'm closing!
Please upgrade with npm install mjml@next to use the latest beta.
I somehow can't include it anymore in any way using node.js ...
In the HTML always occurs this error:
<!-- mj-include fails to read file : ./common-footer.mjml at /.../common-footer.mjml -->
In any configuration describe above
Can you try to pass down { filePath: process.cwd() } as option to see if it does work ?
No sorry, doesn't work
Ok, and { filePath: path.join(__dirname, "emails", "email.mjml") } ?
Yes, that worked :)
But it's not possible (anymore) to leave out the .mjml suffix.
I don't know if this is the intended behavior? 馃
In my use-case, i loaded up the template in a different folder, and this worked:
My file tree:
/emails/global/footer.mjml
/emails/welcome/html.mjml
/utils/mailer.js
My html.mjml:
<mj-include path="./../global/footer.mjml" />
My mailer.js to load the template:
var templatePath = path.resolve(__dirname, '../emails/welcome/html.mjml);
var mjmlTemplate = fs.readFileSync(templatePath, 'utf8');
var htmlTemplate = mjml2html.default(mjmlTemplate, {filePath: path.resolve(__dirname, "../emails/global/email.mjml")}).html;
email.mjml does not exists, it just needs a file with an extension in order to work.
This is what worked for med:
File tree:
/mail.js
/templates/hello.mjml
/components/header.mjml
/components/footer.mjml
hello.mjml
<mjml lang="en">
<mj-body>
<mj-include path="__dirname/../components/header.mjml" />
<mj-text>Hello</mj-text>
<mj-include path="__dirname/../components/footer.mjml" />
</mj-body>
</mjml>
mail.js
export const sendHello = () => {
const mjmlTemplate = fs.readFileSync(`${__dirname}/templates/hello.mjml`, 'utf8');
const { html }聽= mjml2html(, {
filePath: path.join(__dirname, 'components'),
});
// send email..
}
@nomadoda thank!
I will just add a comment to give more description because I needed time to understand your code.
In filePath prop pass the path to your common files such as header, footer, etc.
Most helpful comment
This is what worked for med:
File tree:
hello.mjml
mail.js