{"id":13878913,"url":"https://github.com/sighmon/mjml-rails","last_synced_at":"2025-07-16T14:33:22.696Z","repository":{"id":44878068,"uuid":"57874227","full_name":"sighmon/mjml-rails","owner":"sighmon","description":"MJML + ERb/Haml/Slim view template","archived":false,"fork":true,"pushed_at":"2025-04-07T22:28:18.000Z","size":883,"stargazers_count":313,"open_issues_count":20,"forks_count":69,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-07-03T05:42:27.381Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://mjml.io","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"robotex82/markerb","license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sighmon.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["sighmon"],"ko_fi":"sighmon"}},"created_at":"2016-05-02T08:11:25.000Z","updated_at":"2025-06-14T18:59:38.000Z","dependencies_parsed_at":"2023-02-14T03:16:30.653Z","dependency_job_id":null,"html_url":"https://github.com/sighmon/mjml-rails","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/sighmon/mjml-rails","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sighmon%2Fmjml-rails","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sighmon%2Fmjml-rails/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sighmon%2Fmjml-rails/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sighmon%2Fmjml-rails/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sighmon","download_url":"https://codeload.github.com/sighmon/mjml-rails/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sighmon%2Fmjml-rails/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265518475,"owners_count":23780967,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-08-06T08:02:04.083Z","updated_at":"2025-07-16T14:33:22.258Z","avatar_url":"https://github.com/sighmon.png","language":"Ruby","funding_links":["https://github.com/sponsors/sighmon","https://ko-fi.com/sighmon"],"categories":["Tools","Ruby"],"sub_categories":[],"readme":"# MJML-Rails\n\n[![Build Status](https://github.com/sighmon/mjml-rails/workflows/test/badge.svg?branch=master)](https://github.com/sighmon/mjml-rails/actions?query=workflow%3Atest+branch%3Amaster) [![Gem Version](https://badge.fury.io/rb/mjml-rails.svg)](https://badge.fury.io/rb/mjml-rails)\n\n**MJML-Rails** allows you to render HTML emails from an [MJML](https://mjml.io) template.\n\n**Note**: As of MJML 4.3.0 you can no longer use `\u003cmj-text\u003e` directly inside an `\u003cmj-body\u003e`, wrap it in `\u003cmj-section\u003e\u003cmj-column\u003e`.\n\nAn example template might look like:\n\n```erb\n\u003c!-- ./app/views/user_mailer/user_signup_confirmation.mjml --\u003e\n\u003cmjml\u003e\n  \u003cmj-head\u003e\n    \u003cmj-preview\u003eHello World\u003c/mj-preview\u003e\n  \u003c/mj-head\u003e\n  \u003cmj-body\u003e\n    \u003cmj-section\u003e\n      \u003cmj-column\u003e\n        \u003cmj-text\u003eHello World\u003c/mj-text\u003e\n        \u003c%= render partial: \"info\", formats: [:html] %\u003e\n      \u003c/mj-column\u003e\n    \u003c/mj-section\u003e\n  \u003c/mj-body\u003e\n\u003c/mjml\u003e\n```\n\nAnd the partial:\n\n```erb\n\u003c!-- ./app/views/user_mailer/_info.html.erb --\u003e\n\u003cmj-text\u003eThis is \u003c%= @user.username %\u003e\u003c/mj-text\u003e\n```\n\n* Notice you can use ERB and partials inside the template.\n\nYour `user_mailer.rb` might look like this:\n\n```ruby\n# ./app/mailers/user_mailer.rb\nclass UserMailer \u003c ActionMailer::Base\n  def user_signup_confirmation\n    mail(to: \"user@example.com\", from: \"app@example.com\") do |format|\n      format.text\n      format.mjml\n    end\n  end\nend\n```\n\n## Example application\n\n* [MJML with Rails 6](https://github.com/dyanagi/example_mjml_rails): Renders HTML emails with MJML layout, view, and partial.\n\n## Installation\n\n### Using MJML NPM package\n\nAdd it to your Gemfile.\n\n```ruby\ngem 'mjml-rails'\n```\n\nRun the following command to install it:\n\n```console\nbundle install\n```\n\nAfter installation, you can generate the MJML initializer file:\n\n```console\nrails generate mjml:install\n```\n\nThis will create `config/initializers/mjml.rb` with default configuration options.\n\nAdd the MJML parser to your project with your favourite package manager:\n\n```console\n# with npm\nnpm install mjml\n\n# or install it globally (The best way for Rails 7.x.x with importmaps)\nnpm install -g mjml\n\n# with yarn\nyarn add mjml\n\n# with bun\nbun add mjml\n```\n\nMJML-Rails falls back to a global installation of MJML but it is strongly recommended to add MJML directly to your project.\n\nYou'll need at least Node.js version 6 for MJML to function properly.\n\n### Using MRML with included binaries\n\nIf for some reason you can't or don't want to run JS code in your production environment, you can use [MRML](https://github.com/hardpixel/mrml-ruby). It ships with already compiled binaries for Rust implementation of MJML so it has no external dependencies.\n\nAdd `mjml-rails` and `mrml` to your Gemfile.\n\n```ruby\ngem 'mjml-rails'\ngem 'mrml'\n```\n\nRun the following command to install it:\n\n```console\nbundle install\n```\n\nSet `use_mrml` option to `true` in your initializer:\n\n```ruby\n# config/initializers/mjml.rb\nMjml.setup do |config|\n  config.use_mrml = true\nend\n```\n\n**Note**: MRML does not fully support all MJML functionalities, see [Missing implementations](https://github.com/jdrouet/mrml#missing-implementations)\n\n## Configuration\n\nMJML-Rails has the following settings with defaults:\n\n- `template_language: :erb`\n\n   ERB can be used inside MJML templates by default. Possible values are all template languages that you have installed, e.g. `:haml` or `:slim`.\n\n   **Note:** If you're using Haml/Slim layouts, please don't put `\u003cmjml\u003e` in comments in your partial. Read more at [#34](https://github.com/sighmon/mjml-rails/issues/34).\n\n- `raise_render_exception: true`\n\n   Exceptions will be raised and passed to your application by default.\n\n   Beware that setting it to `false` leads to an empty html email when an exception is raised, so only set this to `false` if you do not rely on html (e.g. you have a text fallback for your emails).\n\n- `minify: false`\n\n- `beautify: true`\n\n- `validation_level: \"strict\"`\n\n   MJML-Rails will raise an exception on any template error by default.\n\n   If set to `soft`, MJML will render invalid templates and ignore invalid parts. This means in case of an invalid template those invalid parts will be missing from the output.\n\n   See [MJML validation documentation](https://github.com/mjmlio/mjml/tree/master/packages/mjml-validator#validating-mjml) for all possible values.\n\n- `mjml_binary: nil`\n\n   This can be used to specify the path to a custom MJML binary if it is not detected automatically (shouldn't be needed).\n\n- `mjml_binary_version_supported: \"4.\"`\n\n   MJML-Rails checks the version of the MJML binary and fails if it does not start with this version, e.g. if an old version is installed by accident.\n\n- `use_mrml: false`\n  Enabling this will allow you to use Rust implementation of MJML via the `mrml` gem. It comes with prebuilt binaries instead of having to install MJML along with Node. When enabled the options `mjml_binary_version_supported`, `mjml_binary`, `minify`, `beautify` and `validation_level` are ignored.\n\n- `cache_mjml: false`\n  By default, MJML-Rails does not cache compiled templates. Setting this to `true` will cache compiled templates in `tmp/mjml_cache` to improve performance for frequently used templates.\n\n- `fonts`\n  By default, MJML-Rails uses MJML default fonts, but enables you to override it.\n  Example : `config.fonts = { Raleway: 'https://fonts.googleapis.com/css?family=Raleway }`\n\n\n```ruby\n# config/initializers/mjml.rb\nMjml.setup do |config|\n  # Use :haml as a template language\n  config.template_language = :haml\n\n  # Ignore errors silently\n  config.raise_render_exception = false\n\n  # Optimize the size of your emails\n  config.beautify = false\n  config.minify = true\n\n  # Render MJML templates with errors\n  config.validation_level = \"soft\"\n\n  # Use MRML instead of MJML, false by default\n  config.use_mrml = false\n\n  # Use custom MJML binary with custom version\n  config.mjml_binary = \"/path/to/custom/mjml\"\n  config.mjml_binary_version_supported = \"3.3.5\"\n\n  # Use default system fonts instead of google fonts\n  config.fonts = {}\n\n  # Uncomment this to enable template caching\n  # config.cache_mjml = true\nend\n```\n\n### MJML v3.x \u0026 v4.x support\n\nVersion 4.x of this gem brings support for MJML 4.x\n\nVersion 2.3.x and 2.4.x of this gem brings support for MJML 3.x\n\nIf you'd rather still stick with MJML 2.x then lock the mjml-rails gem:\n\n```ruby\ngem 'mjml-rails', '2.2.0'\n```\n\nFor MJML 3.x lock the mjml-rails gem:\n\n```ruby\ngem 'mjml-rails', '2.4.3'\n```\n\nAnd then to install MJML 3.x\n\n```console\nnpm install -g mjml@3.3.5\n```\n\n### How to guides\n\n[Kitty Giraudel](https://twitter.com/KittyGiraudel) wrote a post on [using MJML in Rails](http://dev.edenspiekermann.com/2016/06/02/using-mjml-in-rails/).\n\n## Using Email Layouts\n\n*Note*: [Aleksandrs Ļedovskis](https://github.com/aleksandrs-ledovskis) kindly updated the gem for better Rails Email Layouts support - it should be a non-breaking change, but check the updated file naming below if you experience problems.\n\nMailer:\n```ruby\n# mailers/my_mailer.rb\nclass MyMailer \u003c ActionMailer::Base\n  layout \"default\"\n\n  def foo_bar(user)\n    @recipient = user\n\n    mail(to: user.email, from: \"app@example.com\") do |format|\n      format.html # This will look for \"default.html.erb\" and then \"default.html.mjml\"\n    end\n  end\nend\n```\n\nNote: If `default.html.erb` exists, email will be rendered as ERB, and MJML tags will not be compiled.\n\nEmail layout:\n```html\n\u003c!-- views/layouts/default.html.mjml --\u003e\n\u003cmjml\u003e\n  \u003cmj-body\u003e\n    \u003c%= yield %\u003e\n  \u003c/mj-body\u003e\n\u003c/mjml\u003e\n```\n\nEmail view:\n```html\n\u003c!-- views/my_mailer/foo_bar.html.mjml (or foo_bar.html.erb) --\u003e\n\u003c%= render partial: \"to\" %\u003e\n\n\u003cmj-section\u003e\n  \u003cmj-column\u003e\n    \u003cmj-text\u003e\n      Something foo regarding bar!\n    \u003c/mj-text\u003e\n  \u003c/mj-column\u003e\n\u003c/mj-section\u003e\n```\n\nEmail partial:\n```html\n\u003c!-- views/my_mailer/_to.html.mjml (or _to.html.erb) --\u003e\n\u003cmj-section\u003e\n  \u003cmj-column\u003e\n    \u003cmj-text\u003e\n      Hello \u003c%= @recipient.name %\u003e,\n    \u003c/mj-text\u003e\n  \u003c/mj-column\u003e\n\u003c/mj-section\u003e\n```\n\n## Sending Devise user emails\n\nIf you use [Devise](https://github.com/plataformatec/devise) for user authentication and want to send user emails with MJML templates, here's how to override the [devise mailer](https://github.com/plataformatec/devise/blob/master/app/mailers/devise/mailer.rb):\n```ruby\n# app/mailers/devise_mailer.rb\nclass DeviseMailer \u003c Devise::Mailer\n  def reset_password_instructions(record, token, opts={})\n    @token = token\n    @resource = record\n    # Custom logic to send the email with MJML\n    mail(\n      template_path: 'devise/mailer',\n      from: \"some@email.com\",\n      to: record.email,\n      subject: \"Custom subject\"\n    ) do |format|\n      format.text\n      format.mjml\n    end\n  end\nend\n```\n\nNow tell devise to user your mailer in `config/initializers/devise.rb` by setting `config.mailer = 'DeviseMailer'` or whatever name you called yours.\n\nAnd then your MJML template goes here: `app/views/devise/mailer/reset_password_instructions.mjml`\n\nDevise also have [more instructions](https://github.com/plataformatec/devise/wiki/How-To:-Use-custom-mailer) if you need them.\n\n## Deploying with Heroku\n\nTo deploy with [Heroku](https://heroku.com) you'll need to setup [multiple buildpacks](https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app) so that Heroku first builds Node for MJML and then the Ruby environment for your app.\n\nOnce you've installed the [Heroku Toolbelt](https://toolbelt.heroku.com/) you can setup the buildpacks from the commandline:\n\n`$ heroku buildpacks:set heroku/ruby`\n\nAnd then add the Node buildpack to index 1 so it's run first:\n\n`$ heroku buildpacks:add --index 1 heroku/nodejs`\n\nCheck that's all setup by running:\n\n`$ heroku buildpacks`\n\nNext you'll need to setup a `package.json` file in the root, something like this:\n\n```json\n{\n  \"name\": \"your-site\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Now with MJML email templates!\",\n  \"main\": \"index.js\",\n  \"directories\": {\n    \"doc\": \"doc\",\n    \"test\": \"test\"\n  },\n  \"dependencies\": {\n    \"mjml\": \"^4.0.0\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/your-repo/your-site.git\"\n  },\n  \"keywords\": [\n    \"mailer\"\n  ],\n  \"author\": \"Your Name\",\n  \"license\": \"ISC\",\n  \"bugs\": {\n    \"url\": \"https://github.com/sighmon/mjml-rails/issues\"\n  },\n  \"homepage\": \"https://github.com/sighmon/mjml-rails\"\n}\n```\n\nThen `$ git push heroku master` and it should Just WorkTM.\n\n## Bug reports\n\nIf you discover any bugs, feel free to create an issue on GitHub. Please add as much information as possible to help us fixing the possible bug. We also encourage you to help even more by forking and sending us a pull request.\n\n[github.com/sighmon/mjml-rails/issues](https://github.com/sighmon/mjml-rails/issues)\n\n## Maintainers\n\n* Simon Loffler [github.com/sighmon](https://github.com/sighmon)\n* Steven Pickles [github.com/thatpixguy](https://github.com/thatpixguy)\n* [The Rails community](https://github.com/sighmon/mjml-rails/pulls?q=is%3Apr+is%3Aclosed). :-)\n\n## Other similar gems\n\n* [srghma/mjml-premailer](https://github.com/srghma/mjml-premailer)\n* [kolybasov/mjml-ruby/](https://github.com/kolybasov/mjml-ruby/)\n\n## License\n\nMIT License. Copyright 2018 Simon Loffler. [sighmon.com](http://sighmon.com)\n\nLovingly built on [github.com/plataformatec/markerb](https://github.com/plataformatec/markerb)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsighmon%2Fmjml-rails","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsighmon%2Fmjml-rails","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsighmon%2Fmjml-rails/lists"}