Code Monkey home page Code Monkey logo

email-templates's Introduction

build status code coverage code style styled with prettier made with lass license

Create, preview, and send custom email templates for Node.js. Highly configurable and supports automatic inline CSS, stylesheets, embedded images and fonts, and much more! Made for sending beautiful emails with Lad.

NEW: v3.x is released; see breaking changes below. 2.x branch docs available if necessary.

Table of Contents

Install

By default we recommend pug for your template engine, but you can use any template engine.

npm:

npm install email-templates pug

yarn:

yarn add email-templates pug

Preview

We've added preview-email by default to this package!

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.

View the demo

Usage

UPGRADING? If you are upgrading from v2 to v3, see v3 Breaking Changes below.

Basic

You can swap the transport option with a 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.

const Email = require('email-templates');

const email = new Email({
  message: {
    from: '[email protected]'
  },
  // uncomment below to send emails in development/test env:
  // send: true
  transport: {
    jsonTransport: true
  }
});

email.send({
  template: 'mars',
  message: {
    to: '[email protected]'
  },
  locals: {
    name: 'Elon'
  }
}).then(console.log).catch(console.error);

The example above assumes you have the following directory structure:

.
├── app.js
└── emails
    └── mars
        ├── html.pug
        └── subject.pug

And the contents of the pug files are:

html.pug:

p Hi #{name},
p Welcome to Mars, the red planet.

subject.pug:

= `Hi ${name}, welcome to Mars`

Automatic Inline CSS via Stylesheets

Simply include the path or URL to the stylesheet in your template's <head>:

link(rel="stylesheet", href="/css/app.css", data-inline)

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:

const email = new Email({
  // <https://github.com/Automattic/juice>
  juice: true,
  juiceResources: {
    preserveImportant: true,
    webResources: {
      // default path is `build/`:
      relativeTo: path.resolve('build')
      //
      // but you might want to change it to something like:
      // relativeTo: path.join(__dirname, '..', 'assets')
      //
    }
  }
});

Cache Pug Templates

We strongly suggest to follow this example and 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.

  1. Ensure you have Redis (v4.x+) installed:

    • Mac: brew install redis && brew services start redis

    • Ubuntu:

      sudo add-apt-repository -y ppa:chris-lea/redis-server
      sudo apt-get update
      sudo apt-get -y install redis-server
  2. Install the packages:

    npm:

    npm install cache-pug-templates redis

    yarn:

    yarn add cache-pug-templates redis
  3. Configure it to read and cache your entire email templates directory:

    const path = require('path');
    const cachePugTemplates = require('cache-pug-templates');
    const redis = require('redis');
    const Email = require('email-templates');
    
    const redisClient = redis.createClient();
    const email = new Email({
      message: {
        from: '[email protected]'
      },
      transport: {
        jsonTransport: true
      }
    });
    
    cachePugTemplates(redisClient, email.config.views.root);
    
    // ...
  4. For more configuration options see cache-pug-templates.

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).

const Email = require('email-templates');

const email = new Email({
  message: {
    from: '[email protected]'
  },
  transport: {
    jsonTransport: true
  },
  i18n: {} // <------ HERE
});

email.send({
  template: 'mars',
  message: {
    to: '[email protected]'
  },
  locals: {
    name: 'Elon'
  }
}).then(console.log).catch(console.error);

Then slightly modify your templates to use localization functions.

html.pug:

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

subject.pug:

= t(`Hi ${name}, welcome to Mars`)

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

p: :translate(locale) Hi #{name}
p: :translate(locale) Welcome to Mars, the red planet.

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 set config.htmlToText: false (doing so will automatically lookup a text template file just like it normally would for html and subject).

const Email = require('email-templates');

const email = new Email({
  message: {
    from: '[email protected]'
  },
  transport: {
    jsonTransport: true
  },
  htmlToText: false // <----- HERE
});

email.send({
  template: 'mars',
  message: {
    to: '[email protected]'
  },
  locals: {
    name: 'Elon'
  }
}).then(console.log).catch(console.error);

text.pug:

| Hi #{name},
| Welcome to Mars, the red planet.

Custom Template Engine (e.g. EJS)

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

    npm:

    npm install ejs

    yarn:

    yarn add ejs
  2. Set the extension in options and send an email

    const Email = require('email-templates');
    
    const email = new Email({
      message: {
        from: '[email protected]'
      },
      transport: {
        jsonTransport: true
      },
      views: {
        options: {
          extension: 'ejs' // <---- HERE
        }
      }
    });

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:

const Email = require('email-templates');

const email = new Email({
  message: {
    from: '[email protected]',
    headers: {
      'X-Some-Custom-Thing': 'Some-Value'
    },
    list: {
      unsubscribe: 'https://niftylettuce.com/unsubscribe'
    }
  },
  transport: {
    jsonTransport: true
  }
});

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.

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

const ejs = require('ejs');

const email = new Email({
  // ...
  render: (view, locals) => {
    return new Promise((resolve, reject) => {
      // this example assumes that `template` returned
      // is an ejs-based template string
      db.templates.findOne({ view }, (err, template) => {
        if (err) return reject(err);
        if (!template) return reject(new Error('Template not found'));
        resolve(ejs.render(template, locals));
      });
    });
  }
});

Options

For a list of all available options and defaults view the configuration object.

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.

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

V3 Breaking Changes

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

  1. 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 path.resolve('emails') (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:
    -const newsletter = new EmailTemplate(templateDir);
    +const email = new Email({
    +  views: { root: templateDir }
    +});
  2. Instead of calling newsletter.render(locals, callback) you now call email.render(locals). The return value of email.render when invoked is a Promise and does not accept a callback function.

    -newsletter.render({}, (err, result) => {
    -  if (err) return console.error(err);
    -  console.log(result);
    -});
    +email.render({}).then(console.log).catch(console.error);
  3. Localized template directories are no longer supported. We now support i18n translations out of the box. See Localization for more info.

  4. 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.

  5. 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.

  6. 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.

Contributors

Name Website
Nick Baugh http://niftylettuce.com

License

MIT © Nick Baugh

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.