Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Mjml Sidecar Laravel Package

spatie/mjml-sidecar

Compile MJML email templates to responsive HTML via AWS Lambda using Sidecar. A companion to spatie/mjml-php: deploy the provided MjmlFunction, then call Mjml::new()->sidecar()->toHtml($mjml) to render HTML without local Node/MJML.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/mjml-sidecar
    

    Requires spatie/mjml-php (installed automatically as a dependency).

  2. First Use Case: Compile an MJML template directly in a Laravel controller or service:

    use Spatie\MjmlSidecar\Facades\Mjml;
    
    $html = Mjml::compile('
        <mjml>
            <mj-body>
                <mj-section>
                    <mj-column>
                        <mj-text>Hello, World!</mj-text>
                    </mj-column>
                </mj-section>
            </mj-body>
        </mjml>
    ');
    
  3. Where to Look First:

    • Facade API in the README.
    • Mjml-php docs for MJML syntax reference.
    • config/mjml.php (auto-generated) for configuration options.

Implementation Patterns

Core Workflows

  1. Template Compilation:

    • From Strings:
      $html = Mjml::compile($mjmlString);
      
    • From Files:
      $html = Mjml::compileFile(resource_path('views/emails/welcome.mjml'));
      
    • From Views (Laravel-specific):
      $html = Mjml::compileView('emails.welcome', ['name' => 'John']);
      
  2. Integration with Mailables:

    use Spatie\MjmlSidecar\Facades\Mjml;
    use Illuminate\Mail\Mailable;
    
    class WelcomeMail extends Mailable {
        public function build() {
            return $this->subject('Welcome!')
                ->markdown('emails.welcome')
                ->withMjml(function ($mjml) {
                    $mjml->compileView('emails.welcome.mjml', ['name' => $this->name]);
                });
        }
    }
    

    (Note: Requires custom logic to replace the default HTML content.)

  3. Caching Compiled Output:

    $html = Mjml::compile($mjmlString, cache: true); // Caches for 1 hour by default
    $html = Mjml::compile($mjmlString, cache: ['minutes' => 30]);
    
  4. Error Handling:

    try {
        $html = Mjml::compile($mjmlString);
    } catch (\Spatie\MjmlSidecar\Exceptions\MjmlException $e) {
        report($e);
        $html = '<p>Fallback HTML</p>'; // Graceful degradation
    }
    

Advanced Patterns

  • Dynamic MJML Generation: Use Blade templates to generate MJML dynamically:

    $mjml = view('emails.dynamic_mjml', ['data' => $data])->render();
    $html = Mjml::compile($mjml);
    
  • Sidecar Configuration: Override Sidecar settings in config/mjml.php:

    'sidecar' => [
        'timeout' => 30, // seconds
        'memory_limit' => '512M',
    ],
    
  • Testing: Mock the facade in tests:

    $this->mock(Spatie\MjmlSidecar\Facades\Mjml::class)
         ->shouldReceive('compile')
         ->once()
         ->andReturn('<html>...</html>');
    

Gotchas and Tips

Pitfalls

  1. Sidecar Dependencies:

    • Requires Sidecar to be installed and running.
    • Fix: Ensure Sidecar is accessible (default: http://localhost:4444). Configure via config/mjml.php:
      'sidecar' => [
          'url' => env('MJML_SIDECAR_URL', 'http://localhost:4444'),
      ],
      
  2. MJML Syntax Errors:

    • Sidecar may return cryptic errors. Use Mjml::validate($mjmlString) to pre-check syntax:
      if (!Mjml::validate($mjmlString)) {
          throw new \InvalidArgumentException('Invalid MJML syntax');
      }
      
  3. Caching Quirks:

    • Cached responses are stored using Laravel’s cache driver.
    • Tip: Clear cache when MJML templates change:
      php artisan cache:clear
      
  4. Memory Limits:

    • Complex MJML templates may hit Sidecar’s memory limit.
    • Tip: Increase memory_limit in config/mjml.php or simplify templates.
  5. Facade vs. Direct Usage:

    • Avoid instantiating Spatie\MjmlSidecar\Mjml directly; use the facade for consistency.

Debugging Tips

  • Enable Sidecar Logging: Add to config/mjml.php:

    'sidecar' => [
        'debug' => env('APP_DEBUG', false),
    ],
    

    Logs will appear in Laravel’s log channel.

  • Inspect Sidecar Requests: Use a tool like Postman or curl to test Sidecar directly:

    curl -X POST http://localhost:4444/compile -H "Content-Type: text/mjml" -d @template.mjml
    
  • Fallback to mjml-php: If Sidecar fails, fall back to the original spatie/mjml-php:

    use Spatie\Mjml\Mjml;
    
    $html = Mjml::compile($mjmlString, [
        'use_sidecar' => false,
    ]);
    

Extension Points

  1. Custom Compilers: Extend the facade to add pre/post-processing:

    Mjml::extend(function ($compiler) {
        $compiler->afterCompile(function ($html) {
            return str_replace('{app_name}', config('app.name'), $html);
        });
    });
    
  2. Sidecar Middleware: Add middleware to Sidecar requests (e.g., auth, rate limiting) by overriding the HTTP client in config/mjml.php:

    'sidecar' => [
        'client' => function () {
            return new \GuzzleHttp\Client([
                'timeout' => 30,
                'headers' => [
                    'Authorization' => 'Bearer ' . env('SIDECAR_TOKEN'),
                ],
            ]);
        },
    ],
    
  3. Event Listeners: Listen for compilation events (e.g., log templates):

    use Spatie\MjmlSidecar\Events\MjmlCompiled;
    
    MjmlCompiled::listen(function ($event) {
        \Log::debug('Compiled MJML for: ' . $event->template);
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport