evanschleret/lara-mjml

Just a service provider for Spatie's MJML wrapper

Fund package maintenance!
EvanSchleret

Installs: 6 389

Dependents: 0

Suggesters: 0

Security: 0

Stars: 13

Watchers: 2

Forks: 0

Open Issues: 1

pkg:composer/evanschleret/lara-mjml

v0.3 2025-11-11 14:22 UTC

README

Latest Version on Packagist

Laravel MJML integration made simple.

πŸš€ Installation

You can install the package via composer. Also install the MJML npm package as a dependency.

composer require evanschleret/lara-mjml
npm i mjml

Publish the configuration (optional):

Publish the config file to customize the package configuration and add additional options to the MJML binary.

php artisan vendor:publish --provider="EvanSchleret\LaraMjml\Providers\LaraMjmlServiceProvider"

Environment Variables and Configuration

You can set the path to the MJML binary in your .env file.

MJML_NODE_PATH=null
LARA_MJML_BEAUTIFY=false
LARA_MJML_MINIFY=true
LARA_MJML_KEEP_COMMENTS=false

🧩 How It Works

LaraMJML hooks into Laravel’s view system and lets you write MJML templates using Blade syntax. It compiles the MJML to HTML before sending the email.

Just add the .mjml extension to your Blade template files and use MJML tags as you normally would.

Blade hierarchy

The layout should contain the and tags and includes .mjml extension before .blade.php extension.

The views extending the layout should not contain the and tags nor the .mjml extension before .blade.php extension.

βœ… Correct

resources/views/layouts/base.mjml.blade.php
resources/views/emails/welcome.blade.php

❌ Incorrect

resources/views/layouts/base.mjml.blade.php
resources/views/emails/welcome.mjml.blade.php

βœ‰οΈ Usage with Mailable

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class WelcomeMail extends Mailable
{
    use Queueable, SerializesModels;

    public string $user;

    /**
     * Create a new message instance.
     */
    public function __construct(string $user)
    {
        $this->user = $user;
    }

    /**
     * Get the message envelope.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'Welcome Mail',
        );
    }

    /**
     * Get the message content definition.
     */
    public function content(): Content
    {
        return new Content(
            view: 'emails.welcome',
            with: [
                'user' => $this->user,
            ]
        );
    }
}

Then send it:

Mail::to($user->email)->send(
    new WelcomeMail('Welcome !', ['user' => $user])
);

// usage with notification

πŸ”” Usage with Notification

<?php

namespace App\Notifications;

use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class WelcomeNotification extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     */
    public function __construct(
        private readonly User $user,
    )
    { }
    
    /**
     * Get the notification's delivery channels.
     *
     * @return array<int, string>
     */
    public function via(object $notifiable): array
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     */
    public function toMail(object $notifiable): MailMessage
    {
        return new MailMessage()
            ->subject('Welcome !')
            ->view('emails.welcome', [
                'user' => $this->user,
            ]);
    }
}

Then call it:

$user->notify(new WelcomeNotification($user));

βš™οΈ Configuration

The config/laramjml.php file controls:

  • MJML binary path
  • whether to beautify or minify
  • comment preservation
  • custom MJML configuration options

πŸ§ͺ Testing

composer test

🧰 Troubleshooting

  • Empty or broken HTML β†’ ensure only the layout contains and .
  • MJML binary missing β†’ ensure npx mjml runs successfully from your project root.
  • Spatie\Mjml\Exceptions\CouldNotConvertMjml Error: Malformed MJML. Check that your structure is correct and enclosed in tags β†’ avoid .mjml suffix in child filenames.

πŸ§‘β€πŸ’» Contributing

Pull requests welcome!

Changelog

Please see CHANGELOG for more information on what has changed recently.

License

The MIT License (MIT). Please see License File for more information.