You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express中Handlebars邮件模板失效,发送空白邮件求助

问题分析与解决方案

你遗漏了Nodemailer与Handlebars模板引擎的关联配置,同时还有几处细节错误需要修正:

核心问题:未给Nodemailer绑定模板处理器

你当前仅配置了Express的Handlebars引擎,但Nodemailer需要单独通过nodemailer-express-handlebars绑定模板处理逻辑,Express的模板配置不会自动作用于邮件发送。

具体修正步骤

1. 补全缺失的模块引入

代码中使用了path但未引入,同时需要显式引入nodemailer-express-handlebars:

const nodemailer = require('nodemailer');
const sesTransport = require('nodemailer-ses-transport');
const express = require('express');
const exphbs = require('express-handlebars');
const hbs = require('nodemailer-express-handlebars'); // 新增
const path = require('path'); // 新增
const app = express();
app.use(express.json());

2. 移除冗余的Express模板配置(可选)

如果你的服务仅用Handlebars处理邮件模板,不需要渲染网页,可以删除Express的模板配置,因为Nodemailer会单独配置:

// 以下代码可删除(仅保留Express网页渲染场景)
// app.engine('.hbs', exphbs.engine({...}));
// app.set('view engine', '.hbs');
// app.set('views', path.join(__dirname, 'views'));

3. 给Nodemailer Transporter配置模板引擎

创建Transporter实例后,注册nodemailer-express-handlebars作为模板处理器,同时指定模板路径:

// 先创建SES Transporter实例(需补全你的AWS密钥信息)
const transporter = nodemailer.createTransport(sesTransport({
  accessKeyId: '你的AWS Access Key',
  secretAccessKey: '你的AWS Secret Key',
  region: '你的SES服务区域'
}));

// 配置Nodemailer的Handlebars模板规则
transporter.use('compile', hbs({
  viewEngine: exphbs.engine({
    defaultLayout: 'main',
    extname: '.hbs',
    layoutsDir: path.join(__dirname, 'views', 'layouts'),
    partialsDir: path.join(__dirname, 'views', 'partials')
  }),
  viewPath: path.join(__dirname, 'views'), // 指定邮件模板文件所在目录
  extName: '.hbs'
}));

4. 修正模板文件结构与配置

  • 在views目录下创建实际的邮件内容模板,比如views/email-content.hbs
  • 发送邮件时,template字段指定的是该模板文件名(无需后缀):
const options = {
  from: 'mailbox@******.in',
  to: '********@gmail.com',
  subject: 'Test email',
  template: 'email-content', // 对应views/email-content.hbs
  context: {
    name: 'John Doe',
    message: 'This is a test email.'
  }
};
  • 确保layouts/main.hbs包含{{{body}}}占位符,用来渲染模板内容:
<!-- views/layouts/main.hbs -->
<!DOCTYPE html>
<html>
<head>
  <title>{{subject}}</title>
</head>
<body>
  {{{body}}} <!-- 必须保留该占位符,否则模板内容无法渲染 -->
</body>
</html>

5. 确认Transporter实例已正确初始化

你的代码中直接调用了transporter.sendMail,但未展示Transporter的创建逻辑,需确保已用SES密钥完成配置,否则邮件无法正常发送。

常见排查点

  • 用console.log(path.join(__dirname, 'views'))打印路径,验证模板目录是否正确
  • 模板文件扩展名必须与配置的extName一致
  • Layout文件中的{{{body}}}不能省略(三重花括号避免HTML转义)

内容的提问来源于stack exchange,提问作者Mithun Jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 13:07:54