PHPackages                             maize-tech/laravel-mjml - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Mail &amp; Notifications](/categories/mail)
4. /
5. maize-tech/laravel-mjml

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

maize-tech/laravel-mjml
=======================

Responsive MJML emails for Laravel

1.1.0(1mo ago)2487[1 PRs](https://github.com/maize-tech/laravel-mjml/pulls)MITPHPPHP ^8.3CI passing

Since Jun 23Pushed 1mo ago4 watchersCompare

[ Source](https://github.com/maize-tech/laravel-mjml)[ Packagist](https://packagist.org/packages/maize-tech/laravel-mjml)[ Docs](https://github.com/maize-tech/laravel-mjml)[ RSS](/packages/maize-tech-laravel-mjml/feed)WikiDiscussions main Synced 2w ago

READMEChangelog (2)Dependencies (14)Versions (4)Used By (0)

Laravel MJML
============

[](#laravel-mjml)

[![Latest Version on Packagist](https://camo.githubusercontent.com/5c2784f383aa62c3df4fb7535e3f4170cdc777eb7e3ce86482fa977441d72d62/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d61697a652d746563682f6c61726176656c2d6d6a6d6c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/maize-tech/laravel-mjml)[![GitHub Tests Action Status](https://camo.githubusercontent.com/c975e5b387f511eac0eb84821e5fe4c5ea72f1e950828e6a748600d81b8e1b2e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d61697a652d746563682f6c61726176656c2d6d6a6d6c2f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/maize-tech/laravel-mjml/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/c9254915908d14866f7da154aa5faaa7daee3f62a5bf8b57854571b836a26dd0/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6d61697a652d746563682f6c61726176656c2d6d6a6d6c2f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/maize-tech/laravel-mjml/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Total Downloads](https://camo.githubusercontent.com/547b1edd6bfb7c4ab48df334a691c86e053f19332157a6f9f769332b620a599f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6d61697a652d746563682f6c61726176656c2d6d6a6d6c2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/maize-tech/laravel-mjml)

Laravel MJML lets you write responsive HTML emails with [MJML](https://mjml.io/) directly inside your Blade templates. Any view named `*.mjml.blade.php` is first compiled by the Blade engine and then converted to production-ready, email-client-safe HTML, so you keep the full power of Blade (components, slots, directives, localization) while authoring with MJML's concise, responsive syntax.

The package registers a dedicated `mjml` view engine, ships a set of ready-to-use Blade email components and a notification-friendly `MailMessage`, and supports three conversion backends out of the box: a local Node renderer (default), the hosted MJML API, or your own custom action.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require maize-tech/laravel-mjml
```

You can publish the config file and the views with the install command:

```
php artisan laravel-mjml:install
```

This is the contents of the published config file:

```
use Maize\Mjml\Actions\APIConvert;
use Maize\Mjml\Actions\NodeConvert;
use Maize\Mjml\ConversionMode;

return [

    /*
    |--------------------------------------------------------------------------
    | Conversion mode
    |--------------------------------------------------------------------------
    |
    | Here you may specify the conversion mode you may wish to use.
    | Available options are:
    | - Maize\Mjml\ConversionMode::Node
    | - Maize\Mjml\ConversionMode::API
    | - Maize\Mjml\ConversionMode::Custom
    |
    | By default, the value is Maize\Mjml\ConversionMode::Node
    |
    */

    'mode' => ConversionMode::Node,

    'node' => [

        /*
        |--------------------------------------------------------------------------
        | Conversion action
        |--------------------------------------------------------------------------
        |
        | Here you may specify the fully qualified class name of the conversion action.
        | By default, the value is Maize\Mjml\Actions\ConvertMjml::class
        |
        */

        'action' => NodeConvert::class,

        /*
        |--------------------------------------------------------------------------
        | Node options
        |--------------------------------------------------------------------------
        |
        | Here you may specify the options to use when converting MJML to HTML.
        | See available options at https://github.com/mjmlio/mjml#inside-nodejs
        |
        */

        'options' => [
            'keepComments' => true,
            'ignoreIncludes' => false,
            'beautify' => false,
            'minify' => false,
        ],
    ],

    'api' => [

        /*
        |--------------------------------------------------------------------------
        | Conversion action
        |--------------------------------------------------------------------------
        |
        | Here you may specify the fully qualified class name of the conversion action.
        | By default, the value is Maize\Mjml\Actions\ApiConvert::class
        |
        */

        'action' => APIConvert::class,

        /*
        |--------------------------------------------------------------------------
        | API Authentication credentials
        |--------------------------------------------------------------------------
        |
        | Here you may specify the basic auth credentials to use the MJML API.
        |
        */

        'auth_user' => env('MJML_API_AUTH_USER'),
        'auth_password' => env('MJML_API_AUTH_PASSWORD'),
    ],

    'custom' => [

        /*
        |--------------------------------------------------------------------------
        | Conversion action
        |--------------------------------------------------------------------------
        |
        | Here you may specify the fully qualified class name of the conversion action.
        |
        */

        'action' => null,

    ],

];
```

Usage
-----

[](#usage)

### Conversion modes

[](#conversion-modes)

The `mode` config option determines how MJML markup is turned into HTML.

`ConversionMode::Node` (the default) renders MJML locally through [`spatie/mjml-php`](https://github.com/spatie/mjml-php), which relies on the `mjml` Node binary:

```
npm install -g mjml
```

`ConversionMode::API` sends the MJML markup to the hosted [MJML API](https://mjml.io/api) and requires the following environment variables:

```
MJML_API_AUTH_USER=your-application-id
MJML_API_AUTH_PASSWORD=your-secret-key
```

`ConversionMode::Custom` lets you provide your own invokable action. It receives the compiled MJML string and must return the rendered HTML:

```
namespace App\Actions;

class MyConvert
{
    public function __invoke(string $value): string
    {
        // convert $value (MJML) into HTML and return it
    }
}
```

```
// config/mjml.php
'mode' => ConversionMode::Custom,

'custom' => [
    'action' => \App\Actions\MyConvert::class,
],
```

### Notifications

[](#notifications)

Use the package's `MailMessage` inside a notification's `toMail` method to render the notification with MJML instead of the default Laravel mail template. It extends Laravel's `MailMessage`, so the familiar fluent API (`greeting`, `line`, `action`, `salutation`, ...) keeps working:

```
use Illuminate\Notifications\Notification;
use Maize\Mjml\MailMessage;

class OrderShipped extends Notification
{
    public function via(object $notifiable): array
    {
        return ['mail'];
    }

    public function toMail(object $notifiable): MailMessage
    {
        return (new MailMessage)
            ->subject('Your order has shipped')
            ->greeting('Hello!')
            ->line('Your order is on its way.')
            ->action('Track your order', url('/orders/123'))
            ->line('Thank you for shopping with us!');
    }
}
```

### Custom MJML views

[](#custom-mjml-views)

Any view whose name ends with `.mjml.blade.php` is automatically compiled by Blade and converted to HTML. You can use it like any other Blade view — for example as a mailable view:

```
{{-- resources/views/emails/welcome.mjml.blade.php --}}

                Welcome, {{ $name }}!

```

```
use Illuminate\Mail\Mailable;

class WelcomeMail extends Mailable
{
    public function __construct(public string $name)
    {
    }

    public function build(): self
    {
        return $this->view('emails.welcome', [
            'name' => $this->name,
        ]);
    }
}
```

### Blade components

[](#blade-components)

When you publish the views, a set of `x-mjml::*` Blade components becomes available to help you build consistent, well-styled emails:

ComponentDescriptionNotable props`x-mjml::layout`Full email scaffold with header, body, optional subcopy and footer slots.—`x-mjml::message`Notification-style body: greeting, intro/outro lines, action button and salutation.—`x-mjml::header`Top section rendering the application name (or the Laravel logo).`url``x-mjml::footer`Centered footer text (Markdown supported).—`x-mjml::button`Call-to-action button.`url`, `color` (default `#2d3748`), `align` (default `center`)`x-mjml::line`A line of text with Markdown parsing.—`x-mjml::panel`Highlighted panel with a left border.—`x-mjml::subcopy`Secondary text separated by a divider.—Example:

```

        # Hello!

        Thanks for joining us.

        Get started

```

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/maize-tech/.github/blob/main/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](https://github.com/maize-tech/.github/security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Riccardo Dalla Via](https://github.com/riccardodallavia)
- [Enrico De Lazzari](https://github.com/enricodelazzari)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance91

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

45d ago

PHP version history (2 changes)1.0.0PHP ^8.2

1.1.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/848d3feb1799fbdb3ff475a4398017f9bc2b94c5cba4dd69d414af62a856fcc4?d=identicon)[maize-tech](/maintainers/maize-tech)

---

Top Contributors

[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (5 commits)")[![enricodelazzari](https://avatars.githubusercontent.com/u/10452445?v=4)](https://github.com/enricodelazzari "enricodelazzari (5 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (5 commits)")[![riccardodallavia](https://avatars.githubusercontent.com/u/1372062?v=4)](https://github.com/riccardodallavia "riccardodallavia (4 commits)")

---

Tags

laravelMaizelaravel-mjml

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/maize-tech-laravel-mjml/health.svg)

```
[![Health](https://phpackages.com/badges/maize-tech-laravel-mjml/health.svg)](https://phpackages.com/packages/maize-tech-laravel-mjml)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

13.0k107.5M1.6k](/packages/spatie-laravel-permission)[dedoc/scramble

Automatic generation of API documentation for Laravel applications.

2.2k12.6M128](/packages/dedoc-scramble)[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k5.4M49](/packages/spatie-laravel-pdf)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

25060.1k](/packages/vormkracht10-laravel-mails)[codewithdennis/filament-select-tree

The multi-level select field enables you to make single selections from a predefined list of options that are organized into multiple levels or depths.

329575.9k33](/packages/codewithdennis-filament-select-tree)[backstage/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

25094.0k17](/packages/backstage-laravel-mails)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
