npm install dovetailer --save-dev
Dovetailer is one function, which compiles all of the emails in your templates directory.
templatePath: the path to your email templates
partialsPath: the path to your reusable Handlebars partials
const compiler = ;return ;
example-gulpfile.js and an
example-config.js in this repository that you can use as a base for your development environment. It requires Gulp and BrowserSync. I think this a great way to use Dovetailer in development, but you can use Dovetailer however you like. Coming soon: a starter project that you can fork to get going quickly.
templates folder, add another folder for the new template you want to build. Name this folder whatever you want to call your email template.
In that folder, add the following files:
html.handlebars: your Handlebars template for the HTML version
style.scss: your main Sass file (these styles will be automatically inlined)
text.handlebars: your Handlebars template for the text version
content.json: the data file used by Handlebars to compile your template
reset.scss: your Sass file for custom reset styles (see Reset Styles below)
You can also add additional files and folders in your template directory such as Sass partials. See the
example template for, well, an example.
The development and production versions of your email should always render exactly the same (see below) in the browser. There is no development build of the text version, only the HTML version.
The main difference between the development build and the production build is the development build references external stylesheets. The external stylesheets have sourcemaps that point back to the original Sass files. This makes it much easier to develop and debug your emails.
You should use the development build when you're working on coding an email and you're viewing it in a web browser. You should never try to actually send a development build, even just as a test to yourself. It definitely won't work at all.
The production build moves the media queries into the head and groups the styles together by media query. Since CSS is order dependent, in some cases this can produce unexpected results. However, if you follow best practices and keep your Sass organized, you can avoid these issues.
Including "reset" styles helps ensure that your emails render the same across all email clients. There are two different types of reset styles: reset styles that need to be included in the
<head> of the email and reset styles that need to be inlined. Generally,
<head> reset styles are client-specific hacks.
Accordingly, in the included
common folder, there are two reset files named
reset-inline.scss. These are the default sets of reset styles that are included automatically in every email. These files are the result of our research and have been thoroughly tested.
This requires no configuration, but if you want to specify your own set of reset styles for an individual email, you can do so by adding files named
reset-inline.scss to your email's template folder.
If you want to build a responsive email, you're going to need to use media queries. Since it's impossible to inline media queries, your responsive styles will be injected into the
<head> of your HTML.
No extra configuration required! Your media queries will automatically be extracted from your CSS and injected. Also, if you have multiple of the same media query in your stylesheet, the selectors will all be grouped together into a single media query.
For styles in media queries to take any effect in HTML emails, they need to override the internal styles. So, the compiler automatically adds the
!important directive to all styles in media queries.
All compiled Sass files are also run through Autoprefixer, which in most cases will actually act as a minifier by removing extraneous vendor-prefixed styles.
Media query declarations in the same media query rule are packed into one media query rule using CSS MQPacker. This enables you to nest media queries inside of any style rule in Sass without having redundant media query rules in your compiled CSS.
<table>) always get the following HTML attributes:
Empty table cells (
<td>) are automatically filled with a non-breaking space (
). An "empty" table cell is defined to be any table cell that contains either no characters or whitespace only.
Anchor tags (
<a>) always get the following HTML attributes:
<img>) always get the following HTML attributes:
height styles are always applied to
<img>s as width/height HTML attributes.
Dovetailer does its best to look up the dimensions of any
<img> image. It will automatically inject those dimensions as
height HTML attributes as well as
height inline CSS styles. If the image name ends in
@2x, it will assume the image is retina quality, and divide the dimensions in half. Similarly,
@3x images will have dimensions divided by 3. If you specify width/height values for an
<img> using CSS, the natural dimensions are overridden. Image dimensions are cached; if you want to invalidate the cache you can delete/modify
myPartial.hbsa partial will get registered as
myPartial. The file name must have the
templatesfolder while Gulp is running, it will crash Gulp.
templatesfolder while Gulp is running causes an infinite loop?
.hbsnaming syntax for Handlebars files
to empty table cells