{"id":2231,"date":"2025-09-08T10:39:31","date_gmt":"2025-09-08T10:39:31","guid":{"rendered":"https:\/\/www.cmarix.com\/qanda\/?p=2231"},"modified":"2026-02-05T11:59:22","modified_gmt":"2026-02-05T11:59:22","slug":"configure-nodemailer-with-custom-email-templates-in-node-js","status":"publish","type":"post","link":"https:\/\/www.cmarix.com\/qanda\/configure-nodemailer-with-custom-email-templates-in-node-js\/","title":{"rendered":"How to Configure Nodemailer in Node.js with Custom Email Templates"},"content":{"rendered":"\n<p>For many web apps, sending emails is an expected feature. Whether it is for a signup confirmation, password recovery, new password updating, or even promotional offer, a properly designed email improves the user engagement and chances of interaction. If you have a Node.js application you want to integrate email features for, you are at the right place.<\/p>\n\n\n\n<p><strong>In this guide, you&#8217;ll learn how to:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u00a0Set up Nodemailer in Node.js<\/li>\n\n\n\n<li>Send HTML-styled emails using custom templates<\/li>\n\n\n\n<li>Use variables (like user name) in templates<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Configure Nodemailer with Custom Email Templates in Node.js<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: Install Required Packages<\/h3>\n\n\n\n<p>First, let&#8217;s install Nodemailer and optionally handlebars for dynamic templates:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install nodemailer express nodemailer-express-handlebars<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Project Structure<\/h3>\n\n\n\n<p><strong>Here\u2019s a minimal structure:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\ud83d\udce6 email-demo\/\n\u251c\u2500\u2500 \ud83d\udcc1 templates\/\n\u2502   \u2514\u2500\u2500 welcome.handlebars\n\u251c\u2500\u2500 \ud83d\udcc1 utils\/\n\u2502   \u2514\u2500\u2500 mailer.js\n\u251c\u2500\u2500 app.js<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Create an HTML Email Template<\/h3>\n\n\n\n<p><strong>Create templates\/welcome.handlebars:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html>\n&lt;html>\n  &lt;body>\n    &lt;h2>Welcome, {{name}}!&lt;\/h2>\n    &lt;p>Thank you for signing up. We're excited to have you.&lt;\/p>\n    &lt;p>Regards, &lt;br \/>The Team&lt;\/p>\n  &lt;\/body>\n&lt;\/html><\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Configure Nodemailer with Template Support<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>In utils\/mailer.js:\nconst nodemailer = require('nodemailer');\nconst hbs = require('nodemailer-express-handlebars');\nconst path = require('path');\n\n\/\/ Transporter config using Gmail SMTP\nconst transporter = nodemailer.createTransport({\n  service: 'gmail',\n  auth: {\n    user: process.env.MAIL_USER,     \/\/ e.g., yourname@gmail.com\n    pass: process.env.MAIL_PASSWORD, \/\/ your Gmail App password\n  },\n});\n\n\/\/ Template engine config\ntransporter.use('compile', hbs({\n  viewEngine: {\n    extname: '.handlebars',\n    partialsDir: path.resolve('.\/templates'),\n    defaultLayout: false,\n  },\n  viewPath: path.resolve('.\/templates'),\n  extName: '.handlebars',\n}));\n\n\/\/ Send mail function\nconst sendWelcomeEmail = async (toEmail, name) => {\n  const mailOptions = {\n    from: '\"My App\" &lt;no-reply@myapp.com>',\n    to: toEmail,\n    subject: 'Welcome to My App!',\n    template: 'welcome',\n    context: { name }, \/\/ dynamic data\n  };\n\n  try {\n    await transporter.sendMail(mailOptions);\n    console.log(`Email sent to ${toEmail}`);\n  } catch (error) {\n    console.error('Email send error:', error.message);\n  }\n};\n\nmodule.exports = { sendWelcomeEmail };<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Use in Your App<\/h3>\n\n\n\n<p><strong>In app.js:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>require('dotenv').config();\nconst express = require('express');\nconst { sendWelcomeEmail } = require('.\/utils\/mailer');\n\nconst app = express();\napp.use(express.json());\n\napp.post('\/send-welcome', async (req, res) => {\n  const { email, name } = req.body;\n  await sendWelcomeEmail(email, name);\n  res.send('Email sent!');\n});\n\napp.listen(3000, () => console.log('Server running on port 3000'));\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Nodemailer makes it easy to send personalized HTML emails in your Node.js apps using custom templates and variables. It&#8217;s production-friendly and integrates well with most mail providers. If you&#8217;re looking to scale notification systems or improve deliverability, you might want to <strong>hire Node.js developers<\/strong> who know how to build and maintain reliable email infrastructure from day one.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For many web apps, sending emails is an expected feature. Whether it is for a signup confirmation, password recovery, new password updating, or even promotional offer, a properly designed email improves the user engagement and chances of interaction. If you have a Node.js application you want to integrate email features for, you are at the [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":2233,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[18,3],"tags":[],"class_list":["post-2231","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-node-js","category-web"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/2231","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/comments?post=2231"}],"version-history":[{"count":2,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/2231\/revisions"}],"predecessor-version":[{"id":2235,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/posts\/2231\/revisions\/2235"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/media\/2233"}],"wp:attachment":[{"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/media?parent=2231"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/categories?post=2231"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cmarix.com\/qanda\/wp-json\/wp\/v2\/tags?post=2231"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}