Email templates

Create, preview, and send custom Node.js email templates. Automatic inline ...

README

[Email Templates](https://github.com/forwardemail/email-templates)

build status code style styled with prettier made with lass license

Create, [preview][preview-email] (in the browser and in the iOS Simulator), and send custom email templates for [Node.js][node]. Highly configurable and supports automatic inline CSS, stylesheets, embedded images and fonts, and much more! Made for [Forward Email][forward-email] and [Lad][].


Table of Contents


  Basic
  v9.0.0
  v8.0.0
  v7.0.0
  v6.0.0
  v5.0.0
  v4.0.0
  v3.0.0


Install


By default we recommend [pug][] for your template engine, but you can use [any template engine][supported-engines].


[npm][]:

  1. ```sh
  2. npm install email-templates pug
  3. ```


Preview


We've added [preview-email][] by default to this package!  This package allows you to preview emails in the browser and in the iOS Simulator.

This means that (by default) in the development environment (e.g. NODE_ENV=development) your emails will be rendered to the tmp directory for you and automatically opened in the browser.

If you have trouble previewing emails in your browser, you can configure a preview option which gets passed along to [open's options][open-options] (e.g. preview: { open: { app: 'firefox' } }).

See the example below for Open Email Previews in Firefox.


Usage


Debugging


Environment Flag


If you run into any issues with configuration, files, templates, locals, etc, then you can use the NODE_DEBUG environment flag:

  1. ```sh
  2. NODE_DEBUG=email-templates node app.js
  3. ```

This will output to the console all debug statements in our codebase for this package.

Inspect Message


As of v3.6.1 you can now inspect the message passed to nodemailer.sendMail internally.

In the response object from email.send, you have access to res.originalMessage:

  1. ``` js
  2. email
  3.   .send({
  4.     template: 'mars',
  5.     message: {
  6.       to: 'elon@spacex.com'
  7.     },
  8.     locals: {
  9.       name: 'Elon'
  10.     }
  11.   })
  12.   .then(res => {
  13.     console.log('res.originalMessage', res.originalMessage)
  14.   })
  15.   .catch(console.error);
  16. ```

Basic


You can swap the transport option with a [Nodemailer transport][nodemailer-transport] configuration object or transport instance. We highly recommend using [Postmark][] for your transport (it's the default in [Lad][]).

>

If you want to send emails in development or test environments, set options.send to true.


  1. ``` js
  2. const Email = require('email-templates');

  3. const email = new Email({
  4.   message: {
  5.     from: 'test@example.com'
  6.   },
  7.   // uncomment below to send emails in development/test env:
  8.   // send: true
  9.   transport: {
  10.     jsonTransport: true
  11.   }
  12. });

  13. email
  14.   .send({
  15.     template: 'mars',
  16.     message: {
  17.       to: 'elon@spacex.com'
  18.     },
  19.     locals: {
  20.       name: 'Elon'
  21.     }
  22.   })
  23.   .then(console.log)
  24.   .catch(console.error);
  25. ```

The example above assumes you have the following directory structure:

  1. ```sh
  2. .
  3. app.js
  4. emails
  5.      mars
  6.          html.pug
  7.          subject.pug
  8. ```

And the contents of the pug files are:

html.pug:


  1. ```pug
  2. p Hi #{name},
  3. p Welcome to Mars, the red planet.
  4. ```

subject.pug:


  1. ```pug
  2. = `Hi ${name}, welcome to Mars`
  3. ```

Attachments


Please reference [Nodemailer's attachment documentation][attachments] for further reference.

If you want to set default attachments sent with every email:


  1. ``` js
  2. const Email = require('email-templates');

  3. const email = new Email({
  4.   message: {
  5.     from: 'test@example.com',
  6.     attachments: [
  7.       {
  8.         filename: 'text1.txt',
  9.         content: 'hello world!'
  10.       }
  11.     ]
  12.   }
  13. });

  14. email
  15.   .send({
  16.     template: 'mars',
  17.     message: {
  18.       to: 'elon@spacex.com'
  19.     },
  20.     locals: {
  21.       name: 'Elon'
  22.     }
  23.   })
  24.   .then(console.log)
  25.   .catch(console.error);
  26. ```

If you want to set attachments sent individually:


  1. ``` js
  2. const Email = require('email-templates');

  3. const email = new Email({
  4.   message: {
  5.     from: 'test@example.com'
  6.   },
  7.   transport: {
  8.     jsonTransport: true
  9.   }
  10. });

  11. email
  12.   .send({
  13.     template: 'mars',
  14.     message: {
  15.       to: 'elon@spacex.com',
  16.       attachments: [
  17.         {
  18.           filename: 'text1.txt',
  19.           content: 'hello world!'
  20.         }
  21.       ]
  22.     },
  23.     locals: {
  24.       name: 'Elon'
  25.     }
  26.   })
  27.   .then(console.log)
  28.   .catch(console.error);
  29. ```

Automatic Inline CSS via Stylesheets


Simply include the path or URL to the stylesheet in your template's ``:

  1. ```pug
  2. link(rel="stylesheet", href="/css/app.css", data-inline)
  3. ```

This will look for the file /css/app.css in the build/ folder.

If this asset is in another folder, then you will need to modify the default options when creating an Email instance:

  1. ``` js
  2. const email = new Email({
  3.   //
  4.   juice: true,
  5.   // Override juice global settings
  6.   juiceSettings: {
  7.     tableElements: ['TABLE']
  8.   },
  9.   juiceResources: {
  10.     preserveImportant: true,
  11.     webResources: {
  12.       //
  13.       // this is the relative directory to your CSS/image assets
  14.       // and its default path is `build/`:
  15.       //
  16.       // e.g. if you have the following in the ` of your template:
  17.       // ``
  18.       // then this assumes that the file `build/style.css` exists
  19.       //
  20.       relativeTo: path.resolve('build')
  21.       //
  22.       // but you might want to change it to something like:
  23.       // relativeTo: path.join(__dirname, '..', 'assets')
  24.       // (so that you can re-use CSS/images that are used in your web-app)
  25.       //
  26.     }
  27.   }
  28. });
  29. ```

Render HTML and/or Text


If you don't need this module to send your email, you can still use it to render HTML and/or text templates.

Simply use the email.render(view, locals) method we expose (it's the same method that email.send uses internally).

If you need to render a specific email template file (e.g. the HTML version):


  1. ``` js
  2. const Email = require('email-templates');

  3. const email = new Email();

  4. email
  5.   .render('mars/html', {
  6.     name: 'Elon'
  7.   })
  8.   .then(console.log)
  9.   .catch(console.error);
  10. ```

The example above assumes you have the following directory structure (note that this example would only render the html.pug file):

  1. ```sh
  2. .
  3. app.js
  4. emails
  5.      mars
  6.          html.pug
  7.          text.pug
  8.          subject.pug
  9. ```

The Promise for email.render resolves with a String (the HTML or text rendered).

If you need pass juiceResources in render function, with this option you don't need create Email instance every time


  1. ``` js
  2. const Email = require('email-templates');

  3. const email = new Email();

  4. email
  5.   .render({
  6.     path: 'mars/html',
  7.     juiceResources: {
  8.       preserveImportant: true,
  9.       webResources: {
  10.         // view folder path, it will get css from `mars/style.css`
  11.         relativeTo: path.resolve('mars')
  12.       }
  13.     }
  14.   }, {
  15.     name: 'Elon'
  16.   })
  17.   .then(console.log)
  18.   .catch(console.error);
  19. ```

The example above will be useful when you have a structure like this, this will be useful when you have a separate CSS file for every template

  1. ```sh
  2. .
  3. app.js
  4. emails
  5.      mars
  6.          html.pug
  7.          text.pug
  8.          subject.pug
  9.          style.css
  10. ```

The Promise for email.render resolves with a String (the HTML or text rendered).

If you need to render all available template files for a given email template (e.g. html.pug, text.pug, and subject.pug – you can use email.renderAll (this is the method that email.send uses).


  1. ``` js
  2. const Email = require('email-templates');

  3. const email = new Email();

  4. email
  5.   .renderAll('mars', {
  6.     name: 'Elon'
  7.   })
  8.   .then(console.log)
  9.   .catch(console.error);
  10. ```

If you need to render multiple, specific templates at once (but not all email templates available), then you can use Promise.all in combination with email.render:


  1. ``` js
  2. const Email = require('email-templates');

  3. const email = new Email();
  4. const locals = { name: 'Elon' };

  5. Promise
  6.   .all([
  7.     email.render('mars/html', locals),
  8.     email.render('mars/text', locals)
  9.   ])
  10.   .then(([ html, text ]) => {
  11.     console.log('html', html);
  12.     console.log('text', text);
  13.   })
  14.   .catch(console.error);
  15. ```

Cache Pug Templates


Out of the box, templates are cached as they are compiled (e.g. as emails are sent, the template they're using is cached).  However these templates are not cached in-advance, so the first emails sent of each template will be slower to send.

We strongly suggest to pre-cache your templates with [cache-pug-templates][] (if you're using the default [Pug][] template engine).

If you do not do this, then your Pug templates will re-compile and re-cache every time you deploy new code and restart your app.

Note that you will need to specify the views option to your new CachePugTemplates({ views: '...' }); instance, with views being a file path (Array or String) to your email template directory.  See [cache-pug-templates][] documentation for more information.

Localization


All you need to do is simply pass an [i18n][] configuration object as config.i18n (or an empty one as this example shows to use defaults).

Don't want to handle localization and translation yourself? Just use [Lad][lad] – it's built in and uses [mandarin][] (with automatic Google Translate support) under the hood!


  1. ``` js
  2. const Email = require('email-templates');

  3. const email = new Email({
  4.   message: {
  5.     from: 'test@example.com'
  6.   },
  7.   transport: {
  8.     jsonTransport: true
  9.   },
  10.   i18n: {} // <------ HERE
  11. });

  12. email
  13.   .send({
  14.     template: 'mars',
  15.     message: {
  16.       to: 'elon@spacex.com'
  17.     },
  18.     locals: {
  19.       locale: 'en', // <------ CUSTOMIZE LOCALE HERE (defaults to `i18n.defaultLocale` - `en`)
  20.       // is your user french?
  21.       // locale: 'fr',
  22.       name: 'Elon'
  23.     }
  24.   })
  25.   .then(console.log)
  26.   .catch(console.error);
  27. ```

Then slightly modify your templates to use localization functions.

html.pug:


  1. ```pug
  2. p= `${t('Hi')} ${name},`
  3. p= t('Welcome to Mars, the red planet.')
  4. ```

subject.pug:


  1. ```pug
  2. p= `${t('Hi')} ${name}, ${t('welcome to Mars')}`
  3. ```

Note that if you use [Lad][], you have a built-in filter called translate:

  1. ```pug
  2. p: :translate(locale) Welcome to Mars, the red planet.
  3. ```

Localization using Handlebars template engine


If you are using handlebars and you are using localization files with named values, you will quickly see that
there is no way to properly call the t function in your template and specify named values.

If, for example you have this in your translation file:

  1. ``` json
  2. {
  3.   "greetings": "Hi {{ firstname }}",
  4.   "welcome_message": "Welcome to Mars, the red planet."
  5. }
  6. ```

And you would like to use it in your template like this:

html.hbs:


  1. ```handlebars
  2. <p>{{ t "greetings" firstname="Marcus" }}</p>
  3. <p>{{ t "welcome_message" }}</p>
  4. ```

This would not work because the second argument sent by handlebars to the function would be a handlebar helper
options object instead of just the named values.

A possible workaround you can use is to introduce your own translation helper in your template locals:

  1. ``` js
  2. email
  3.   .send({
  4.     template: 'mars',
  5.     message: {
  6.       to: 'elon@spacex.com'
  7.     },
  8.     locals: {
  9.       locale: 'en', // <------ CUSTOMIZE LOCALE HERE (defaults to `i18n.defaultLocale` - `en`)
  10.       // is your user french?
  11.       // locale: 'fr',
  12.       name: 'Elon',
  13.       $t(key, options) {
  14.         // <------ THIS IS OUR OWN TRANSLATION HELPER
  15.         return options.data.root.t(
  16.           { phrase: key, locale: options.data.root.locale },
  17.           options.hash
  18.         );
  19.       }
  20.     }
  21.   })
  22.   .then(console.log)
  23.   .catch(console.error);
  24. ```

Then slightly modify your templates to use your own translation helper functions.

html.hbs:


  1. ```handlebars
  2. <p>{{ $t "greetings" firstname="Marcus" }}</p>
  3. <p>{{ $t "welcome_message" }}</p>
  4. ```

Text-Only Email (no HTML)


If you wish to have only a text-based version of your email you can simply pass the option textOnly: true.

Regardless if you use the htmlToText option or not (see next example), it will still render only a text-based version.

  1. ``` js
  2. const Email = require('email-templates');

  3. const email = new Email({
  4.   message: {
  5.     from: 'test@example.com'
  6.   },
  7.   transport: {
  8.     jsonTransport: true
  9.   },
  10.   textOnly: true // <----- HERE
  11. });

  12. email
  13.   .send({
  14.     template: 'mars',
  15.     message: {
  16.       to: 'elon@spacex.com'
  17.     },
  18.     locals: {
  19.       name: 'Elon'
  20.     }
  21.   })
  22.   .then(console.log)
  23.   .catch(console.error);
  24. ```

Prefix Subject Lines


You can pass an option to prefix subject lines with a string, which is super useful for deciphering development / staging / production environment emails.

For example, you could make it so on non-production environments the email is prefixed with a [DEVELOPMENT] Some Subject Line Here.

You could do this manually by passing a message.subject property, however if you are storing your subject lines in templates (e.g. subject.ejs or subject.pug) then it's not as easy.

Simply use the subjectPrefix option and set it to whatever you wish (note you will need to append a trailing space if you wish to have a space after the prefix; see example below):

  1. ``` js
  2. const Email = require('email-templates');

  3. const env = process.env.NODE_ENV || 'development';

  4. const email = new Email({
  5.   message: {
  6.     from: 'test@example.com'
  7.   },
  8.   transport: {
  9.     jsonTransport: true
  10.   },
  11.   subjectPrefix: env === 'production' ? false : `[${env.toUpperCase()}] `; // <--- HERE
  12. });
  13. ```

Custom Text Template


By default we use html-to-text to generate a plaintext version and attach it as message.text.


If you'd like to customize the text body, you can pass message.text or create a text template file just like you normally would for html and subject.

You may also set config.htmlToText: false to force the usage of the text template file.

  1. ``` js
  2. const Email = require('email-templates');

  3. const email = new Email({
  4.   message: {
  5.     from: 'test@example.com'
  6.   },
  7.   transport: {
  8.     jsonTransport: true
  9.   },
  10.   htmlToText: false // <----- HERE
  11. });

  12. email
  13.   .send({
  14.     template: 'mars',
  15.     message: {
  16.       to: 'elon@spacex.com'
  17.     },
  18.     locals: {
  19.       name: 'Elon'
  20.     }
  21.   })
  22.   .then(console.log)
  23.   .catch(console.error);
  24. ```

text.pug:


  1. ```pug
  2. | Hi #{name},
  3. | Welcome to Mars, the red planet.
  4. ```

Custom Template Engine (e.g. EJS)


1. Install your desired template engine (e.g. [EJS][])

   [npm][]:

  1. ```sh
  2.    npm install ejs
  3. ```

2. Set the extension in options and send an email

  1. ``` js
  2.    const Email = require('email-templates');

  3.    const email = new Email({
  4.      message: {
  5.        from: 'test@example.com'
  6.      },
  7.      transport: {
  8.        jsonTransport: true
  9.      },
  10.      views: {
  11.        options: {
  12.          extension: 'ejs' // <---- HERE
  13.        }
  14.      }
  15.    });
  16. ```

Custom Default Message Options


You can configure your Email instance to have default message options, such as a default "From", an unsubscribe header, etc.

For a list of all available message options and fields see the Nodemailer message reference.

Here's an example showing how to set a default custom header and a list unsubscribe header:


  1. ``` js
  2. const Email = require('email-templates');

  3. const email = new Email({
  4.   message: {
  5.     from: 'test@example.com',
  6.     headers: {
  7.       'X-Some-Custom-Thing': 'Some-Value'
  8.     },
  9.     list: {
  10.       unsubscribe: 'https://example.com/unsubscribe'
  11.     }
  12.   },
  13.   transport: {
  14.     jsonTransport: true
  15.   }
  16. });
  17. ```

Custom Rendering (e.g. from a MongoDB database)


You can pass a custom config.render function which accepts two arguments view and locals and must return a Promise.

Note that if you specify a custom config.render, you should have it use email.juiceResources before returning the final HTML.  The example below shows how to do this.

If you wanted to read a stored EJS template from MongoDB, you could do something like:

  1. ``` js
  2. const ejs = require('ejs');

  3. const email = new Email({
  4.   // ...
  5.   render: (view, locals) => {
  6.     return new Promise((resolve, reject) => {
  7.       // this example assumes that `template` returned
  8.       // is an ejs-based template string
  9.       // view = `${template}/html` or `${template}/subject` or `${template}/text`
  10.       db.templates.findOne({ name: view }, (err, template) => {
  11.         if (err) return reject(err);
  12.         if (!template) return reject(new Error('Template not found'));
  13.         let html = ejs.render(template, locals);
  14.         html = await email.juiceResources(html);
  15.         resolve(html);
  16.       });
  17.     });
  18.   }
  19. });
  20. ```

Absolute Path to Templates


As of v5.0.1+ we now support passing absolute paths to templates for rendering (per discussion in #320.

For both email.send and email.render, the template option passed can be a relative path or absolute:

Relative example:


  1. ``` js
  2. email
  3.   .send({
  4.     template: 'mars',
  5.     message: {
  6.       to: 'elon@spacex.com'
  7.     },
  8.     locals: {
  9.       name: 'Elon'
  10.     }
  11.   })
  12.   .then(console.log)
  13.   .catch(console.error);
  14. ```

Absolute example:


  1. ``` js
  2. const path = require('path');

  3. // ...

  4. email
  5.   .send({
  6.     template: path.join(__dirname, 'some', 'folder', 'mars')
  7.     message: {
  8.       to: 'elon@spacex.com'
  9.     },
  10.     locals: {
  11.       name: 'Elon'
  12.     }
  13.   })
  14.   .then(console.log)
  15.   .catch(console.error);
  16. ```

Open Email Previews in Firefox


The preview option can be a custom Object of options to pass along to [open's options][open-options].

Firefox example:


  1. ``` js
  2. const email = new Email({
  3.   // ...
  4.   preview: {
  5.     open: {
  6.       app: 'firefox',
  7.       wait: false
  8.     }
  9.   }
  10. });
  11. ```


Options


For a list of all available options and defaults view the configuration object, or reference the list below:

views (Object)
  root (String) - defaults to the current working directory's "emails" folder via path.resolve('emails')
  options (Object)
    extension (String) - defaults to 'pug', and is the default file extension for templates
    map (Object) - a template file extension mapping, defaults to { hbs: 'handlebars', njk: 'nunjucks' } (this is useful if you use different file extension naming conventions)
    engineSource (Object) - the default template engine source, defaults to [consolidate][]
  locals (Object) - locals to pass to templates for rendering
    cache (Boolean) - defaults to false for development and test environments, and true for all others (via process.env.NODE_ENV), whether or not to cache templates
    pretty (Boolean) - defaults to true, but is automatically set to false for subject templates and text-based emails
message (Object) - default [Nodemailer message object][nodemailer-message-object] for messages to inherit (defaults to an empty object {})
send (Boolean) - whether or not to send emails, defaults to false for development and test environments, and true for all others (via process.env.NODE_ENV) (NOTE: IF YOU ARE NOT USING NODE_ENV YOU WILL NEED TO MANUALLY SET THIS TO true)
preview (Boolean or Object) - whether or not to preview emails using [preview-email][], defaults to false unless the environment is development (via process.env.NODE_ENV) – if you wish to disable the iOS Simulator then pass { openSimulator: false }
i18n (Boolean or Object) - translation support for email templates, this accepts an I18N configuration object (defaults to false, which means it is disabled) which is passed along to [@ladjs/i18n][i18n] – see Localization example for more insight
render (Function) - defaults to a stable function that accepts two argument, view (String) and locals (Object) - you should not need to set this unless you have a need for custom rendering (see Custom Rendering (e.g. from a MongoDB database))
customRender (Boolean) - defaults to false, unless you pass your own render function, and in that case it will be automatically set to true
textOnly (Boolean) - whether or not to force text-only rendering of a template and disregard the template folder (defaults to false)
htmlToText (Object) - configuration object for [html-to-text][]
  ignoreImage (Boolean) - defaults to true
subjectPrefix (Boolean or String) - defaults to false, but if set to a string it will use that string as a prefix for your emails' subjects
juice (Boolean) - whether or not to use [juice][] when rendering templates (defaults to true) (note that if you have a custom rendering function you will need to implement [juice][] in it yourself)
juiceResources (Object) - options to pass to juice.juiceResources method (only used if juice option is set to true, see [juice's][juice] API for more information
  preserveImportant (Boolean) - defaults to true
  webResources (Object) - an options object that will be passed to [web-resource-inliner][]
    relativeTo (String) - defaults to the current working directory's "build" folder via path.resolve('build') (NOTE: YOU SHOULD MODIFY THIS PATH TO WHERE YOUR BUILD/ASSETS FOLDER IS)
    images (Boolean or Number) - defaults to false, and is  whether or not to inline images unless they have an exclusion attribute (see [web-resource-inliner][] for more insight), if it is set to a Number then that is used as the KB threshold
transport (Object) - a transport configuration object or a Nodemailer transport instance created via nodemailer.createTransport, defaults to an empty object {}, see [Nodemailer transports][nodemailer-transports] documentation for more insight
getPath (Function) - a function that returns the path to a template file, defaults to function (type, template) { return path.join(template, type); }, and accepts three arguments type, template, and locals


Plugins


You can use any [nodemailer][] plugin. Simply pass an existing transport instance as config.transport.

You should add the [nodemailer-base64-to-s3][] plugin to convert base64 inline images to actual images stored on Amazon S3 and Cloudfront.

When doing so (as of v4.0.2+), you will need to adjust your email-templates configuration to pass images: true as such:

  1. ``` js
  2. const email = new Email({
  3.   // ...
  4.   juiceResources: {
  5.     preserveImportant: true,
  6.     webResources: {
  7.       relativeTo: path.resolve('build'),
  8.       images: true // <--- set this as `true`
  9.     }
  10.   }
  11. });
  12. ```

We also highly recommend to add to your default config.locals the following:

[custom-fonts-in-emails][] - render any font in emails as an image w/retina support (no more Photoshop or Sketch exports!)
[font-awesome-assets][] - render any [Font Awesome][fa] icon as an image in an email w/retina support (no more Photoshop or Sketch exports!)


Breaking Changes


See the Releases page for an up to date changelog.

v10.0.0


This package now requires Node v14+.

v9.0.0


This package now requires Node v10.x+ due to web-resource-inliner dependency.

v8.0.0


We upgraded html-to-text to v6. As a result, automatically generated text versions of your emails will look slightly different, as per the example below:

  1. ```diff
  2. +Hi,
  3. +
  4. +email-templates rocks!
  5. +
  6. +Cheers,
  7. +The team
  8. -Hi,email-templates rocks!
  9. -Cheers,The team
  10. ```

v7.0.0


We upgraded `preview-email` to `v2.0.0`, which supports stream attachments, and additionally the view rendering is slightly different (we simply iterate over header lines and format them in a `
` block).  A major version bump was done due to the significant visual change in the preview rendering of emails.

v6.0.0


Performance should be significantly improved as the rendering of subject, html, and text parts now occurs asynchronously in parallel (previously it was in series and had blocking lookup calls).
We removed [bluebird][] and replaced it with a lightweight alternative [pify][] (since all we were using was the Promise.promisify method from bluebird as well).
This package now only supports Node v8.x+ (due to [preview-email][]'s [open][] dependency requiring it).
Configuration for the preview option has slightly changed, which now allows you to specify a custom template and stylesheets for preview rendering.

  > If you were using a custom preview option before, you will need to change it slightly:

  1. ```diff
  2.   const email = new Email({
  3.     // ...
  4.     preview: {
  5.   +    open: {
  6.   +      app: 'firefox',
  7.   +      wait: false
  8.   +    }
  9.   -    app: 'firefox',
  10.   -    wait: false
  11.     }
  12.   });
  13. ```

v5.0.0


In version 4.x+, we changed the order of defaults being set.  See #313 for more information.  This allows you to override message options such asfrom (even if you have a global default from set).

v4.0.0


See v5.0.0 above

v3.0.0


If you are upgrading from v2 or prior to v3, please note that the following breaking API changes occurred:


1. You need to have Node v6.4.0+, we recommend using nvm to manage your Node versions.

2. Instead of calling const newsletter = new EmailTemplate(...args), you now call const email = new Email(options).

   The arguments you pass to the constructor have changed as well.
   Previously you'd pass new EmailTemplate(templateDir, options).  Now you will need to pass simply one object with a configuration as an argument to the constructor.
   If your templateDir path is the "emails" folder in the root of your project (basically ./emails folder) then you do not need to pass it at all since it is the default per the configuration object.
   The previous value for templateDir can be used as such:

  1. ```diff
  2.    -const newsletter = new EmailTemplate(templateDir);
  3.    +const email = new Email({
  4.    +  views: { root: templateDir }
  5.    +});
  6. ```

   Note that if you are inlining CSS, you should also make sure that the option for juiceResources.webResources.relativeTo is accurate.

3. Instead of calling newsletter.render(locals, callback) you now call email.render(template, locals).  The return value of email.render when invoked is a Promise and does not accept a callback function.

   > NOTE: email-templates v3 now has an email.send method (see basic usage example) which usesnodemailer; you should now use email.send instead of email.render!

  1. ```diff
  2.    -newsletter.render({}, (err, result) => {
  3.    -  if (err) return console.error(err);
  4.    -  console.log(result);
  5.    -});
  6.    +email.render(template, {}).then(console.log).catch(console.error);
  7. ```

4. Localized template directories are no longer supported.  We now support i18n translations out of the box.  See Localization for more info.

5. A new method email.send has been added.  This allows you to create a Nodemailer transport and send an email template all at once (it calls email.render internally).  See the Basic usage documentation above for an example.

6. There are new options options.send and options.preview.  Both are Boolean values and configured automatically based off the environment.  Take a look at the configuration object.  Note that you can optionally pass an Object topreview option, which gets passed along to [open's options][open-options].

7. If you wish to send emails in development or test environment (disabled by default), set options.send to true.


Tip


Instead of having to configure this for yourself, you could just use [Lad][] instead.


Related


[lad][] - Scaffold a [Koa][] webapp and API framework for [Node.js][node]
[lass][] - Scaffold a modern boilerplate for [Node.js][node]
[cabin][] - Logging and analytics solution for [Node.js][node], [Lad][], [Koa][], and [Express][]
[forward-email][] - Free, encrypted, and open-source email forwarding service for custom domains


Contributors


NameWebsite
---------------------------------------
**Nick


License




##

[node]: https://nodejs.org

[npm]: https://www.npmjs.com/

[pug]: https://pugjs.org

[supported-engines]: https://github.com/tj/consolidate.js/#supported-template-engines

[nodemailer]: https://nodemailer.com/plugins/

[font-awesome-assets]: https://github.com/ladjs/font-awesome-assets

[custom-fonts-in-emails]: https://github.com/ladjs/custom-fonts-in-emails

[nodemailer-base64-to-s3]: https://github.com/ladjs/nodemailer-base64-to-s3

[lad]: https://lad.js.org

[i18n]: https://github.com/ladjs/i18n#options

[fa]: http://fontawesome.io/

[nodemailer-transport]: https://nodemailer.com/transports/

[postmark]: https://postmarkapp.com/

[ejs]: http://ejs.co/

[cache-pug-templates]: https://github.com/ladjs/cache-pug-templates

[preview-email]: https://github.com/forwardemail/preview-email

[attachments]: https://nodemailer.com/message/attachments/

[lass]: https://lass.js.org

[cabin]: https://cabinjs.com

[forward-email]: https://forwardemail.net

[koa]: https://koajs.com/

[express]: https://expressjs.com

[open-options]: https://github.com/sindresorhus/open#options

[mandarin]: https://github.com/ladjs/mandarin

[consolidate]: https://github.com/tj/consolidate.js

[nodemailer-message-object]: https://nodemailer.com/message/

[html-to-text]: https://github.com/werk85/node-html-to-text

[web-resource-inliner]: https://github.com/jrit/web-resource-inliner

[nodemailer-transports]: https://nodemailer.com/transports/

[juice]: https://github.com/Automattic/juice

[bluebird]: https://github.com/petkaantonov/bluebird

[pify]: https://github.com/sindresorhus/pify

[open]: https://github.com/sindresorhus/open