English | العربية | বাংলা | Bosanski | Deutsch | Español | Français | हिन्दी | Italiano | 日本語 | 한국어 | मराठी | Português | Русский | Kiswahili | தமிழ் | తెలుగు | Türkçe | اردو | Tiếng Việt | 中文
- Upgrading
- Introduction
- Installation
- Usage (Without Laravel)
- Usage (With Laravel)
- Configuration
- Support Guidelines
- License - MIT License
Upgrading
If you are upgrading from a previous version, please see the Upgrade Guide for breaking changes and migration steps.
Introduction
MJML is a markup language specifically designed to simplify the process of coding responsive emails. Its semantic syntax ensures ease and simplicity, while its extensive library of standard components accelerates development and reduces the complexity of your email codebase. The open-source engine of MJML generates high-quality, responsive HTML that adheres to best practices. If you've experienced the frustrations of working with Outlook, this package is tailored for you.
Our MJML implementation serves as a wrapper for the official MJML API. It enables convenient compilation of MJML into HTML directly within PHP, without the need for NodeJS. This package is ideal for PHP applications that wish to incorporate MJML without the hassle of installing NodeJS and the MJML CLI.
Example
// Without Laravel(new MJML)->render( '<mjml><mj-body><mj-section><mj-column><mj-text>Hello World</mj-text></mj-column></mj-section></mj-body></mjml>'); // Minified HTML(new MJML)->minify()->render( '<mjml><mj-body><mj-section><mj-column><mj-text>Hello World</mj-text></mj-column></mj-section></mj-body></mjml>'); // With LaravelMJML::render( '<mjml><mj-body><mj-section><mj-column><mj-text>Hello World</mj-text></mj-column></mj-section></mj-body></mjml>'); // With Laravel and minified HTMLMJML::minify()->render( '<mjml><mj-body><mj-section><mj-column><mj-text>Hello World</mj-text></mj-column></mj-section></mj-body></mjml>');
Installation
-
First add the following to your
composer.jsonfile to instruct our package to pull the correct binaries for your operating system when our package is installed. The binaries will download after you runinstall,update, ordump-autoload.{"post-autoload-dump": ["DefectiveCode\\MJML\\PullBinary::all"]}The MJML binary will be obtained from our CDN and saved in the "bin" folder of this package during composer's installation or update. Ensure that you have the necessary binaries loaded for both your local and production environments.
By default,
allwill pull all binaries we support. We recommend scoping this down to the operating and architecture systems you need to save on bandwidth and install times. The following are the available binaries.Operating System Architecture Composer Post Update Command All All DefectiveCode\MJML\PullBinary::allDarwin (MacOS) arm64 DefectiveCode\MJML\PullBinary::darwin-arm64Darwin (MacOS) x64 DefectiveCode\MJML\PullBinary::darwin-x64Linux (glibc) arm64 DefectiveCode\MJML\PullBinary::linux-arm64Linux (glibc) x64 DefectiveCode\MJML\PullBinary::linux-x64Linux (musl) arm64 DefectiveCode\MJML\PullBinary::linux-arm64-muslLinux (musl) x64 DefectiveCode\MJML\PullBinary::linux-x64-musl -
Next, install the PHP package by running the following composer command:
composer require defectivecode/mjml -
That's it! If using Laravel, our package will automatically install using Laravel's package discovery.
Usage (Without Laravel)
See the usage with Laravel below if you are using Laravel.
Rendering MJML
To render MJML, simply pass your MJML string to the render method:
use DefectiveCode\MJML; $html = (new MJML)->render( '<mjml><mj-body><mj-section><mj-column><mj-text>Hello World</mj-text></mj-column></mj-section></mj-body></mjml>');
Validating MJML
To validate MJML, simply pass your MJML string to the isValid method:
use DefectiveCode\MJML; $isValid = (new MJML)->isValid( '<mjml><mj-body><mj-section><mj-column><mj-text>Hello World</mj-text></mj-column></mj-section></mj-body></mjml>');
Usage (With Laravel)
Rendering MJML
To render MJML, simply pass your MJML string to the render on the MJML facade:
use DefectiveCode\MJML\Facades\MJML; $html = MJML::render( '<mjml><mj-body><mj-section><mj-column><mj-text>Hello World</mj-text></mj-column></mj-section></mj-body></mjml>');
Validating MJML
To validate MJML, simply pass your MJML string to the isValid method on the MJML facade:
use DefectiveCode\MJML\Facades\MJML; $isValid = MJML::isValid( '<mjml><mj-body><mj-section><mj-column><mj-text>Hello World</mj-text></mj-column></mj-section></mj-body></mjml>');
Configuration
You may publish the configuration file using the following command:
php artisan vendor:publish --provider="DefectiveCode\MJML\MJMLServiceProvider"
This will create a mjml.php configuration file in your config folder. All the options listed in the configuration
file are past to the config object when you use the MJML facade.
Configuration
All configuration options can be set by calling the following methods directly on the MJML object.
use DefectiveCode\MJML; $html = (new MJML) ->setMinify(true) ->setBeautify(false) ->render( '<mjml><mj-body><mj-section><mj-column><mj-text>Hello World</mj-text></mj-column></mj-section></mj-body></mjml>' );
Our package follows the same configuration as the official MJML package except for the following:
preprocessors- This option is not available. Please open a pull request if you would like to add this option.minifyOptions- We use a lightweight PHP-based minifier instead ofhtml-minifier. The minifier removes comments (except Outlook conditionals), collapses whitespace, and removes whitespace between tags.
Fonts
Our package uses the following fonts by default:
- Open Sans: 'https://fonts.googleapis.com/css?family=Open+Sans:300,400,500,700
- Droid Sans: 'https://fonts.googleapis.com/css?family=Droid+Sans:300,400,500,700
- Lato: https://fonts.googleapis.com/css?family=Lato:300,400,500,700
- Roboto: https://fonts.googleapis.com/css?family=Roboto:300,400,500,700
- Ubuntu: https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700
You may change the fonts by using the following methods:
addFont(string $font, string $url)- Add a font to the list of fonts.removeFont(string$font)- Remove a font from the list of fonts.setFonts(array $fonts)- Set the list of fonts. You should provide an array of fonts in this format:['font-name' => 'font-url'].
Comments
Comments are kept by default. If you wish to remove comments, you may use the removeComments() method.
You may also revert the removeComments() by calling the keepComments() method.
Ignore Includes
By default, our package will include any mj-include tags. You may adjust
this behavior by calling the ignoreIncludes(bool $ignore) method.
Beautify
Our package will beautify the HTML using js-beautify with the following
default options:
- indentSize: 2
- wrapAttributesIndentSize: 2
- maxPreserveNewline: 0
- preserveNewlines: false
While
js-beautifyuses snake_case to provide options, you should use camelCase when using our package. We made this choice to keep our package consistent with the rest of the configuration options. Our package will automatically convert the camelCase options to snake_case.
You may override any of these options by providing a valid js-beautify configuration using the following methods:
setBeautifyOptions(array $options)- Set thejs-beautifyoptions.addBeautifyOption(string $option, mixed $value)- Adds ajs-beautifyoption.removeBeautifyOption(string $option)- Removes ajs-beautifyoption.
Minify
Our package will minify the HTML output when enabled. Minification performs the following:
- Removes HTML comments (preserves Outlook conditional comments like
<!--[if mso]>) - Collapses multiple whitespace characters into single spaces
- Removes whitespace between HTML tags
You may enable or disable minification by calling the minify(bool $minify) method.
Why PHP-based minification? The official MJML package uses
html-minifierfor minification, which has a known ReDoS vulnerability (CVE-2022-37620) with no fix available as the package is unmaintained. To avoid bundling vulnerable dependencies, we moved minification to PHP using a lightweight, secure implementation.
Validation Level
Our package will validate the MJML using the soft validation level by default. You may change this by using the
validationLevel(ValidationLevel $validationLevel) method. The following validation levels are available:
strict- Your document is going through validation and is not rendered if it has any errorsoft- Your document is going through validation and is rendered, even if it has errorsskip- Your document is rendered without going through validation.
File Path
Our package will use the . directory by default. You may change this by using calling the filePath(string $path)
method.
Juice
We do not provide any juice options by default. You may add juice options by using the following methods:
setJuiceOptions(array $options)- Set the juice options.addJuiceOption(string $option, mixed $value)- Adds a juice option.removeJuiceOption(string $option)- Removes a juice option.setJuicePreserveTags(array $tags)- Set the juice preserve tags.addJuicePreserveTag(string $tag, mixed $value)- Adds a juice preserve tag.removeJuicePreserveTag(string $tag)- Removes a juice preserve tag.
Support Guidelines
Thanks for choosing our open source package! Please take a moment to check out these support guidelines. They'll help you get the most out of our project.
Community Driven Support
Our open-source project is fueled by our awesome community. If you have questions or need assistance, StackOverflow and other online resources are your best bets.
Bugs, and Feature Prioritization
The reality of managing an open-source project means we can't address every reported bug or feature request immediately. We prioritize issues in the following order:
1. Bugs Affecting Our Paid Products
Bugs that impact our paid products will always be our top priority. In some cases, we may only address bugs that affect us directly.
2. Community Pull Requests
If you've identified a bug and have a solution, please submit a pull request. After issues affecting our products, we give the next highest priority to these community-driven fixes. Once reviewed and approved, we'll merge your solution and credit your contribution.
3. Financial Support
For issues outside the mentioned categories, you can opt to fund their resolution. Each open issue is linked to an order form where you can contribute financially. We prioritize these issues based on the funding amount provided.
Community Contributions
Open source thrives when its community is active. Even if you're not fixing bugs, consider contributing through code improvements, documentation updates, tutorials, or by assisting others in community channels. We highly encourage everyone, as a community, to help support open-source work.
To reiterate, DefectiveCode will prioritize bugs based on how they impact our paid products, community pull requests, and the financial support received for issues.
License - MIT License
Copyright © Defective Code, LLC. All rights reserved
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.