How to create HTML email templates on Amazon SES

How to create HTML email templates on Amazon SES

In a previous blog post, we discussed how Amazon SES is the most affordable way to send reliable emails (with some tradeoffs to consider). In this blog post, we'll share an example on how to create email templates within Amazon SES (see examples of email templates).

Creating an Amazon SES template

Unfortunately, email templates can't be created from the Amazon SES dashboard, so we'll use code to setup the template.

To do this, we'll use the npm library for Amazon SES. Install with:

npm i @aws-sdk/client-sesv2


In the code example below, we're creating an HTML template in the htmlBody variable and then passing that to Amazon SES.

Note the dynamic variable name in the template body. Amazon SES allows for Handlebars templating within the template for variables, conditionals, partials, and more. We'll pass in the dynamic data while sending the email on the next step.

const { CreateEmailTemplateCommand, SendEmailCommand, SESv2Client } = require('@aws-sdk/client-sesv2');

// Replace these variables with your AWS credentials and SES configuration
const awsAccessKey = AWS_ACCESS_KEY;
const awsSecretKey = AWS_SECRET_KEY;
const region = AWS_REGION;

// Content used to create the HTML Template
const templateName = 'your template name';
const subject = 'Your Email Subject';
const htmlBody = `
    <html>
    <head></head>
    <body>
        <h1>Hello, {{name}}!</h1>
        <p>This is a sample email template.</p>
    </body>
    </html>
`;

const fromEmail = FROM_EMAIL;
const toEmail = TO_EMAIL;

const client = new SESv2Client({
  region: region,
  credentials: {
    accessKeyId: awsAccessKey,
    secretAccessKey: awsSecretKey,
  },
});

const createTemplateCommand = new CreateEmailTemplateCommand({
  TemplateName: templateName,
  TemplateContent: {
    Subject: subject,
    Html: htmlBody,
  },
});

await client.send(createTemplateCommand);


Sending emails through an SES template

When we're ready to send an email, we'll use SendEmailCommand to pass data to our template. The data is just the variables that our template is expecting in order to populate the template. In this simple example, it's just the name.

const sendCommand = new SendEmailCommand({
  FromEmailAddress: fromEmail,
  Destination: {
    ToAddresses: [toEmail],
  },
  Content: {
    Template: {
      TemplateName: templateName,
      TemplateData: '{"name": "Jordan"}', // Replace with your dynamic content
    },
  },
});

await client.send(sendCommand);

Assuming everything was configured properly, after running the code, our email should be sent with the template data populated.

Tip: you can monitor delivery of these emails by connecting Amazon SES to Amazon SNS – learn more.

A note on HTML email templates

For simple HTML emails with minimal formatting, writing raw HTML for templates works just fine.

However, when it comes to advanced formatting (eg. layouts, buttons, branding), the code for these templates quickly becomes a mess to maintain. This is primarily due to the challenges of cross-client support which forces developers to write 90s style HTML with inline CSS paired with tables within tables within tables. For details on cross-client support, caniemail.com is a wonderful resource.

To help remedy this, developers often use email template frameworks like MJML. These frameworks abstract many of these pain points into a highly reusable component based system that works across clients out of the box.


Looking for a more collaborative approach?

While component libraries are a step in the right direction, product teams often find that this approach can still lead to significant developer bottlenecks since template code is still within their codebase. This means every time a template needs to be adjusted or marketing wants to test different copy, a developer is needed for changes, pull requests, deploys, etc.

This is why some collaborative teams opt for a new approach – adding a collaboration layer on top of their Amazon SES. Waypoint Connect has a powerful template builder geared for data-rich emails and emails are routed through your own AWS IAM account.

Screenshot of Waypoint’s powerful transactional email template builder. Emails are routed through your own AWS with Waypoint Connect.


The added benefit of Waypoint Connect is much better observability as well.

Screenshot of Waypoint Connect’s logs on a single email (populated from your Amazon SNS events).


Wrap up

Let's face it, Amazon SES is hard to beat on price. But as we discussed in a previous blog post, SES is like buying wholesale and has it's limitations. For teams that want to collaborate around product emails, it's worth considering alternative approach with a collaboration layer on top of Amazon SES (with Waypoint Connect).