DEV Community

Cover image for Dynamic emails with handlebars and nodemailer
Nick Smet
Nick Smet

Posted on

Dynamic emails with handlebars and nodemailer

Ever tried writing a dynamic email in HTML & CSS? If so, did you like it? Probably not.

It’s a dreaded task that we’d love to pass on to marketing. Or anyone for that matter.

But sometimes it’s not possible. So we decided to hack something together that might make it slightly less painful to draft emails with variables - especially transactional emails.

We hope it means you get a MailChimp-like experience without using MailChimp.

Demo URL: https://handlebars-email-html-previewer.vercel.app/

Image description

The preview app does three main things:

  1. Let’s you draft/modify a HTML template with variables containing handlebars & instantly preview it in the browser
  2. Put some test variables into JSON to see that they’re working
  3. Send a test email to Mailtrap

Note: right now we don’t save your template anywhere but we plan to implement this later. For now, copy-paste and don’t close the tab!

You can see the client code here and the server code that connects with Mailtrap here.

How we built the Editor

We wanted to have a nice coding experience in the browser so we tried out a ton of different packages including:

But we found them all either difficult to work with, outdated or a bit laggy for us. They’re probably all great but we didn’t have time so we moved on if we couldn’t get it working smoothly quickly.

Image description

Finally, I came across a comment on Reddit suggesting Monaco because VSCode is built on top of it.

Monaco worked perfectly out the box (except for a tiny bit of flashing when you type)

It also had some really nice advanced features like autocomplete and a map view.

It was also really easy to implement.

import Editor from "@monaco-editor/react";

interface Props {
    code: string;
    onChange: (code: string) => void;
}

function MyEditor(props: Props) {
  return (
      <Editor
          value={props.code}
          language="handlebars"
          defaultValue="Please enter HTML code."
          theme="vs-dark"
          onChange={(newvalue?: string) => props.onChange(newvalue || '')}
      />
  );
}

export default MyEditor;
Enter fullscreen mode Exit fullscreen mode

It pretty much works the same as a text box where you update the state on change.

As you can see we also changed it to dark mode 😎

Image description

Using Handlebars to add variables

Handlebars are commonly used in HTML emails to make them dynamic. You can use it like so

Your HTML code
...
<p>{{name}}</p>
...
Enter fullscreen mode Exit fullscreen mode

The opening and closing brackets indicate a handlebar variable, more information can be found here.

Then we use the Handlebars compiler to turn our HTML with handlebars variables, to plain HTML with inserted variables.

import Handlebars from 'handlebars';
const data = {
    name: "John"
}

const handlebarsTemplate = Handlebars.compile(YOUR_HTML);
const parsedHtml = handlebarsTemplate(data);

// this transforms the code to 
...
<p>John</p>
...
Enter fullscreen mode Exit fullscreen mode

Handlebars is quite powerful. You can add in conditional logic, loops, etc…

Image description

Previewing the email

But now, the tricky part! How do you know your handlebars actually work with the given data?

That was the whole reason we made this tool, easy validation of our handlebar templates with live previews.

On each code change we update your live preview, so you can see exactly how your code looks, and behaves.

Image description

We also provided a way of inputting test data. Click on the top right corner on “set test data”. This will open up a JSON editor. Here you can add the variables you declared in your HTML template with handlebars, alongside their test data values.

For instance if you have a variable {{name}} in your HTML template, you can create JSON test data like this:

{
    "name":"Satoshi Nakamoto"
}
Enter fullscreen mode Exit fullscreen mode

Sending test emails to Mailtrap

The final feature of this tool allows you to send your preview to your Mailtrap inbox. This is important because the browser preview is not always going to be perfectly accurate.

Click on “Mailtrap” in the top right corner, this will open up the config modal.

You’ll be asked for:

  • Inbox ID: This can be found in the url when you open up your inbox in Mailtrap
  • Api Key: Can be found under settings → API keys in Mailtrap

Image description

You only need to input these once, it will be stored in local storage for easy use afterwards

Then go ahead and click “send test email”! This will send a test email to your mailtrap using a small node application we made (which can be found here). We use this small node server to avoid CORS errors, the only purpose is to take your HTML, and send a request to the mailtrap API.

Further info

We didn’t focus on how to send emails with nodemailer. There are a lot of tutorials out there, here are some suggestions:

Top comments (0)