nest-modules / mailer

📨 A mailer module for Nest framework (node.js)
https://nest-modules.github.io/mailer/
MIT License
837 stars 176 forks source link

Templates with handlebars are not processed - NestJS mailer send blank email #914

Closed carepollo closed 9 months ago

carepollo commented 1 year ago

Describe the bug The mails are sent with no problems, but these emails are sent with a blank body, only can send content when using text or html properties, never with template, in my case the adapter is Handlebars

To Reproduce Steps to reproduce the behavior:

  1. Follow these steps exactly as they are and I get this

Expected behavior Should be possible to send mails with a template and using variables within the property context

Screenshots image

Ignore the destiny email is this a placeholder

Desktop (please complete the following information):

Smartphone (please complete the following information): Doesn't apply

Additional context I have tried these technique before in another app and worked perfectly, but the variables sent in context weren't read or something, is not related to my main issue (blank emails) but is worth to mention.

kodjunkie commented 1 year ago

Use this as your template config

template: {
  dir: join(__dirname, '..', '..', 'mail', 'templates'),
  adapter: new HandlebarsAdapter(), // or new PugAdapter() or new EjsAdapter()
  options: {
    strict: true,
  },
},
malliaridis commented 1 year ago

Having the same issue in 1.8.1. Tried any combination and path, with join() and process.pwd(), as well with and without ./ in the template string. The file paths generated are correct, but for some reason the template is loaded and an empty email is sent.

Using dir: join(__dirname, '..', '..', 'mail', 'templates') will generate according to the example a wrong file path (probably, but didn't fix it anyway). It should be dir: join(__dirname, '..', 'mail', 'templates'). However, none of the combinations I tried did work.

Any other ideas?

P.s. the templates can be found in the correct directory under dist/.

kodjunkie commented 1 year ago

If you use react, then this would help nestjs-mailer-react-adapter

malliaridis commented 1 year ago

I am implementing a backend with nest-js without frontend rendering and making use of Handlebars solely for email template rendering. So I guess the library wouldn't solve the problem?

My current workaround looks as follows:

const templateStr = fs
  .readFileSync(resolve(__dirname, 'templates', 'signup.hbs'))
  .toString('utf8');
const template = Handlebars.compile(templateStr, { noEscape: true });

await this.mailerService.sendMail({
  from: {
    name: 'Sender Name',
    address: 'support@example.com',
  },
  to: email,
  subject: 'Welcome to the Community',
  html: template({ signUpToken }),
});

Similar implementation exists in the HandlebarsAdapter. But this workaround wouldn't make use of the Handlebars-Adapter and module configuration capabilities, so making the library obsolete for that specific use case. :/

I am wondering why it works this way, even if the implementation and paths / files are exactly the same.

carepollo commented 1 year ago

For me it does send content when I hardcode a string with html content on the html property of the options object in the sendMail method., is the only way working until now.

kodjunkie commented 1 year ago

I think your template.dir might be pointed to the wrong path, besides, is it like a must to use handlebars? If not, you have several adapter options.

I addressed this issue with the nestjs-mailer-react-adapter package. Since react is written in tsx, it gets transpiled into the same directory in dist and you won’t have this issue or worry about tweaking nest-cli to copy your template directory.

malliaridis commented 1 year ago

@kodjunkie your solution with tsx is a great alternative I could definitely use it if I wouldn't have to rely on handlebars.

I am using a template generator that generates templates with handlebars. Using other engines would require to manually edit the templates after generation, which would be time-consuming and error-prone. So there is no way around for me at least.

If the template.dir would point to the wrong directory, I assume that other adapters wouldn't work as well. But I got it running with the pug adapter, so I guess that case can be excluded.

If the templates are outside the src directory, you don't have to tweak the nest-cli, but have to copy the other directory as well on deployment. So working with templates is a pain either way. 😅

guiesco-halo commented 1 year ago

I am implementing a backend with nest-js without frontend rendering and making use of Handlebars solely for email template rendering. So I guess the library wouldn't solve the problem?

My current workaround looks as follows:

const templateStr = fs
  .readFileSync(resolve(__dirname, 'templates', 'signup.hbs'))
  .toString('utf8');
const template = Handlebars.compile(templateStr, { noEscape: true });

await this.mailerService.sendMail({
  from: {
    name: 'Sender Name',
    address: 'support@example.com',
  },
  to: email,
  subject: 'Welcome to the Community',
  html: template({ signUpToken }),
});

Similar implementation exists in the HandlebarsAdapter. But this workaround wouldn't make use of the Handlebars-Adapter and module configuration capabilities, so making the library obsolete for that specific use case. :/

I am wondering why it works this way, even if the implementation and paths / files are exactly the same.

this was the only way i could make the template work, compiling them manually. I have tried other template adapters but i couldn't make any of them work

dotoleeoak commented 9 months ago

@juandav Why is this issue closed? It seems the bug is not resolved. I am suffering the same issue for version 1.10.3.

dotoleeoak commented 9 months ago

I've found a workaround. Let me share this for people having this issue. I originally used template with html tag, head tag and body tag like html. After removing the tags, it works just fine. But I'm struggling to find the reason why it fails to render the original template, which worked with the older version of nestjs-modules/mailer.

Before

<html>
  <head>
    <style>
      ...
    </style>
  </head>
  <body>
    <p>
      ...
    </p>
  </body>
</html>

After

<style>
...
</style>

<p>
...
</p>