Reputation: 716
I am using nodemailer to send emails using the following nodemailer-express-handlebars plugin. I used this {dead blog post} as reference
The code is compiling the welcome
template but is not using the layout
My code is as below:
var nodemailer = require('nodemailer');
var mg = require('nodemailer-mailgun-transport');
var hbs = require('nodemailer-express-handlebars');
var config = {auth: {api_key: "key-xxx",domain: "mydomain.com}}
var nodemailerTransport = nodemailer.createTransport(mg(config));
var options = {
viewEngine: {
extname: '.handlebars',
layoutsDir: 'views/email/',
defaultLayout : 'layout',
},
viewPath: 'views/email/'
}
nodemailerTransport.use('compile', hbs(options));
nodemailerTransport.sendMail({
from: '[email protected]',
to: '[email protected]',
subject: 'Welcome to the XXX',
template: 'welcome'
}, function (err, results) {
if (err) console.log('Error: ' + err);
else console.log('Response: ' + results);
});
My layout.handlebars
has the following code
<html>
<body>
{{> _header }}
{{{body}}}
{{> _footer }}
</body>
</html>
Upvotes: 8
Views: 17351
Reputation: 299
Your code looks almost correct, but there is a little problem with the way you specify the default layout in the options object. why not instead of defaultLayout: 'layout', use defaultLayout: 'layout.handlebars'. The full object should look like:
var options = {
viewEngine: {
extname: '.handlebars',
layoutsDir: 'views/email/',
defaultLayout: 'layout.handlebars', // Specify the layout file including the extension
},
viewPath: 'views/email/'
};
Also, make sure the layout.handlebars file is inside the layoutsDir directory and that it is correctly formatted.
Additionally, ensure that the welcome.handlebars template is correctly referencing the layout. It should have something like this:
{{!< layout}}
<!-- Your welcome email content goes here -->
Upvotes: 0
Reputation: 1
import * as handlebars from 'handlebars';
import * as nodemailer from 'nodemailer';
import * as fs from 'fs';
async sendEmail(to: string, subject: string, text: string) {
const templateFile = fs.readFileSync('enter the path of your template(emailTempalate.hbs) ', 'utf-8');
// Compile the Handlebars template
const template = handlebars.compile(templateFile);
// Render the template with the provided context/data
const html = template({ username: 'John Doe' });
const mailOptions = {
from: '[email protected]',
to,
subject,
text,
html,
};
try {
await this.transporter.sendMail(mailOptions);
return { msg: 'Email sent successfully' };
} catch (error) {
console.error('Error sending email:', error);
throw new Error('Failed to send email');
}
}
Upvotes: 0
Reputation: 6211
You are missing a partialsDir
option.
I have tested with the following options and it works fine :
var options = {
extName:'.hbs', /* or '.handlebars' */
viewPath:__dirname+'/views/email/',
layoutsDir:__dirname+'/view/email',
defaultLayout:'template',
partialsDir:__dirname+'/views/email/partials/'
}
To use my directory structure :
views
email
(here store 'template.hbs')partials
folder (here as example store 'header.hbs')Upvotes: 2