yads / nodemailer-express-handlebars

A plugin for nodemailer that uses express-handlebars view engine to generate emails
87 stars 30 forks source link

Error: The partial myPartial could not be found #45

Closed AdriwanKenoby closed 3 years ago

AdriwanKenoby commented 3 years ago

Hi, i am disappointed about partialsDir option.

I set up application in transporter file.

`const nodemailer = require('nodemailer'); const hbs = require('nodemailer-express-handlebars'); const path = require('path'); const transporter = nodemailer.createTransport(process.env.SMTP_URL);

transporter.use('compile', hbs({ viewEngine: { extName: '.hbs', layoutsDir: path.join(dirname, '..', 'views', 'layouts'), partialsDir: path.join(dirname, '..', 'views', 'partials'), defaultLayout: false }, viewPath: path.join(__dirname, '..', 'views'), extName: '.hbs' }));

module.exports = transporter;`

My directory structure :

views |-- layouts | -- layout.hbs |-- partials | -- myPartial.hbs |--email.hbs

`let mail = { from: 'no-reply@cryptochain.org', to: req.user.email, subject: 'Cryptochain Private Key', template: 'email', context: { title: 'Private Key', username: req.user.username, key: req.app.locals.wallet.keyPair.getPrivate('hex') } }

transporter.sendMail(mail, (err, info) => { if(err) { console.error(err); } }); `

layout.hbs `<!doctype html>

{{title}} {{body}}

`

myPartial.hbs `

This is your private key

{{key}}

`

email.hbs <h1>Welcome {{username}}</h1> {{> myPartial }}

But still get the error myPartial is not found

dbertozzi commented 3 years ago

I was able to get my partial working by creating a view engine instead of passing in view engine options.

If I use the same config but pass options in it did not work.

import nodemailer from "nodemailer";
import hbs from "nodemailer-express-handlebars";
import handlebars from "express-handlebars";
import path from "path";

interface nodeMailerResponse {
  accepted: string[];
  rejected: string[];
  envelopeTime: number;
  messageTime: number;
  messageSize: number;
  response: string;
  envelope: {
    from: string;
    to: string;
    messageId: string;
  };
}
const mailerOptions = {
  // your nodemailer options 
};
export async function sendEmail(options: {
  to: string | string[];
  subject: string;
  template: string;
  context?: { [templateVar: string]: string | number | {} };
}): Promise<nodeMailerResponse> {
  const transporter = nodemailer.createTransport(mailerOptions);
  const viewEngine = handlebars.create({
    partialsDir: [path.resolve(__dirname, "./views/partials/")],
    extname: ".hbs",
    // @ts-expect-error
    defaultLayout: false,
  });
  const hbsOptions = {
    viewEngine: viewEngine,
    viewPath: path.resolve(__dirname, "./views"),
    extName: ".hbs",
  };
  transporter.use("compile", hbs(hbsOptions));
  const info: nodeMailerResponse = await transporter.sendMail({
    from: "mail@mail.com",
    ...options,
  });
  return info;
}