{"id":15138694,"url":"https://github.com/davidmarquis/mjml-starter-advanced","last_synced_at":"2026-03-15T21:53:48.034Z","repository":{"id":138625895,"uuid":"75633626","full_name":"davidmarquis/mjml-starter-advanced","owner":"davidmarquis","description":"Rapid responsive email development with MJML (Nunjucks templates and support for i18n and multiparts)","archived":false,"fork":false,"pushed_at":"2023-10-19T19:05:57.000Z","size":36,"stargazers_count":32,"open_issues_count":2,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-23T15:43:40.657Z","etag":null,"topics":["email-boilerplate","email-marketing","i18n","livereload","mjml","nunjucks"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davidmarquis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-12-05T14:41:47.000Z","updated_at":"2024-04-11T19:43:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"c29aaa70-6aa2-44c3-ba89-12cf6fd5c732","html_url":"https://github.com/davidmarquis/mjml-starter-advanced","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/davidmarquis/mjml-starter-advanced","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmarquis%2Fmjml-starter-advanced","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmarquis%2Fmjml-starter-advanced/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmarquis%2Fmjml-starter-advanced/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmarquis%2Fmjml-starter-advanced/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davidmarquis","download_url":"https://codeload.github.com/davidmarquis/mjml-starter-advanced/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidmarquis%2Fmjml-starter-advanced/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30552154,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-15T15:03:43.933Z","status":"ssl_error","status_checked_at":"2026-03-15T15:03:37.630Z","response_time":61,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["email-boilerplate","email-marketing","i18n","livereload","mjml","nunjucks"],"created_at":"2024-09-26T07:43:36.801Z","updated_at":"2026-03-15T21:53:48.003Z","avatar_url":"https://github.com/davidmarquis.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MJML Email Development Starter\n\nThis is a streamlined environment for developing multilingual, multipart emails with focus on DRY and developer productivity.\n\nThe tool lets developers author emails in both HTML and plain text versions that will be compatible with many email clients, thanks to the use of the [MJML](https://mjml.io) library. The output of the tool is a set files for each variant (HTML/text) and language.\n\nThe actual use of the output files is out of this tool's scope. Your application could load the files and send them via SMTP, or you could use the output directly in a marketing email tool such as Mailchimp, Campaign Monitor, etc.\n\nThe tool has the following features:\n\n - HTML Email Templates based on [MJML](https://mjml.io) v3\n - Support for both HTML and text versions of your emails (with complete control over the text version)\n - LiveReload to see changes to HTML emails in near realtime in the browser. \n - Composition/reuse with template inheritance via Nunjucks templates\n - Internationalisation support (i18n)\n\n## How to run this?\n\n\u003e Consider using `nvm` to manage multiple Node versions on your system. \n\nPre-requisites: \n\n - Node (v10) with NPM\n \nPreparing your machine:\n\n    $ npm install gulp -g                   # if needed\n    $ npm install\n\nBuild and start a LiveReload-enabled server for local development:\n\n    $ gulp\n    \nThen hit [http://localhost:1980](http://localhost:1980) to see a listing of all the output files. \nAny file can be open in the browser and every HTML file will be reloaded as you make changes in sources.\n\n## Building for production\n\nRun:\n\n    $ gulp build --env production\n    \nAll files are bundled in the `output` directory and images from `src/assets` will be copied in the `output/assets` directory\n\nArguments:\n\n__`--out`__: Replaces the default output directory (`./output`) with the one provided. Example:\n\n    $ gulp build --env production --out /path/to/your/output/dir/ \n \n## Configuration\n \nA `config.js` file exists to provide configuration parameters for the build. The following attribute is supported:\n\n - **`imageBase`**: The absolute URL where images are to be accessible publicly.\n\n\n## About images\n\nImages in emails are expected to be hosted on a public web server (ex: S3). This tool does not embed images into emails.\n\nAs a convenience for developers when working locally (more specifically using the `development` environment), the image paths will be adjusted so that they point to the local file instead of a fully absolute URL. For that process to work, the `$IMGPATH$` replacement pattern needs to be prepended to all references to images in any of the `.mjml` templates.\n\nExample:\n\n    \u003cmj-image width=\"100\" src=\"$IMGBASE$/logo.gif\" /\u003e\n    \nThis would refer to an image stored in the following directory: `src/assets/logo.gif`.\n\n**Note**: Usage of the `$IMGBASE$` pattern is not required if your images are already on a public server.\n\nIt is not part of the scope of this tool to sync or upload images to a public hosting environment. All the tool does is repatriate every image file under the `src/assets` directory into the `output/assets` directory when building the project. Those files should then be uploaded/synced to a Web server serving static files.\n\nWhen building templates for production (see _Building for production_ below), the `$IMGBASE$` variables will be replaced by the `imageBase` configuration attribute in `config.js`.\n\n## About translations / i18n\n\nThe output of the tool is a different version of each email in both HTML and text version, in all languages that have a corresponding `messages.yaml` file under the `src/locales/[LANG]` directory.\n\nThe `messages.yaml` files is a simple hierarchical data structure that maps keys to the actual value in a specific language.\n\nTo use translated strings in emails, use the following delimiter: `_(messages.[KEY])`, where `[KEY]` is the dot-delimited path that leads to the string you want in `messages.yaml`.\n\nFor example, given a `messages.yaml` file under `src/locales/en` with the following contents:\n\n    footer:\n      from: \"Sent by YourCompany\"\n\nYou would include that translated string in your source files as such: `_(messages.footer.from)`\n\nThe replacement process is setup to work on for all files under `src/templates/html` and `src/templates/text`.\n \n## Dynamic contents\n \nIf your emails are going to be rendered by your application with dynamic contents, make sure you properly escape your dynamic content placeholders if your app's templating language uses similar tags as Nunjucks.\n\nFor example, if you are going to render your final emails using Django's templating language, the `{{ var }}` placeholders are the same as what Nunjucks expects. To keep your dynamic placeholder, escape them with the `{% raw %}` escape tag.\n\n    \u003cp\u003e{% raw %}{{ some_dynamic_variable }}{% endraw %}\u003c/p\u003e\n    \nThis will generate the following output:\n\n    \u003cp\u003e{{ some_dynamic_variable }}\u003c/p\u003e\n\nWithout the `{% raw %}` escape tag, the output would be\n\n    \u003cp\u003e\u003c/p\u003e\n \nThis is because Nunjucks tries to substitute the `{{ some_dynamic_variable }}` placeholder with a variable from its context. Because there is no such variable, the output is simply empty.\n\n## Caveats\n\n### RFC-2822 conformance\n \nMJML tends to generate HTML with very long lines (longer than 998 characters) without any line breaks. Some email clients (ex: Gmail) do not properly deal with long lines in emails, mostly because of the [RFC-2822 - Internet Message Format (see 2.1.1 - Line Length Limits)](https://www.ietf.org/rfc/rfc2822.txt) specification.\n\nThis happens mostly when you nest many MJML components within each other, for example:\n\n``` html\n    \u003cmj-section\u003e\n        \u003cmj-column width=\"50%\"\u003e\n            \u003cmj-button\u003e\n               Click me    \u003c!-- The HTML output could include a line longer than 998 characters --\u003e\n            \u003c/mj-button\u003e   \n        \u003c/mj-column\u003e\n    \u003c/mj-section\u003e\n```\n\nAn observable side effect of those long lines in incompatible clients is often missing/cut/discarded attributes in the final HTML. \n\nA possible solution is to remove some levels of nesting and get rid of the `mj-column` (in that specific case):\n\n``` html\n    \u003cmj-section\u003e\n        \u003cmj-button\u003e\n           Click me    \u003c!-- Lines will be shorter, and more email clients will be happy --\u003e\n        \u003c/mj-button\u003e   \n    \u003c/mj-section\u003e\n```\n\n**Other Workarounds**\n\n 1. Encode your email contents as Base64 when sending them, which will naturally break lines but with a cost of about 20-30% increase on email size.\n 2. Encode your email contents with [`quoted-printable`](https://en.wikipedia.org/wiki/Quoted-printable)\n \n### `mj-include` tag not properly working \n\nThe `\u003cmj-include\u003e` MJML tag does not currently work as there is an issue with the way it tries to find the  files included.\n ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidmarquis%2Fmjml-starter-advanced","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavidmarquis%2Fmjml-starter-advanced","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidmarquis%2Fmjml-starter-advanced/lists"}