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

Laravel Mail Css Inliner Laravel Package

fedeisas/laravel-mail-css-inliner

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require fedeisas/laravel-mail-css-inliner
    

    Publish the config file (optional):

    php artisan vendor:publish --provider="Fedeisas\MailCssInliner\MailCssInlinerServiceProvider" --tag="config"
    
  2. First Use Case: Automatically inline CSS for all outgoing emails by adding the Inliner trait to your Mailable class:

    use Fedeisas\MailCssInliner\Traits\Inliner;
    
    class OrderConfirmationMail extends Mailable
    {
        use Inliner;
    
        // Your Mailable logic...
    }
    

    The package will now inline CSS for every email sent via this class.

  3. Quick Manual Inlining: For one-off emails, use the MailCssInliner facade:

    use Fedeisas\MailCssInliner\Facades\MailCssInliner;
    
    $html = '<html><head><style>body { color: red; }</style></head><body>...</body></html>';
    $inlinedHtml = MailCssInliner::inline($html);
    

Implementation Patterns

Core Workflows

1. Automatic Inlining for All Emails

  • Add the Inliner trait to your base Mailable class (e.g., App\Mail\BaseMailable):
    use Fedeisas\MailCssInliner\Traits\Inliner;
    
    class BaseMailable extends Mailable
    {
        use Inliner;
    }
    
  • Extend this class for all your mailables. CSS will be inlined automatically.

2. Conditional Inlining

Override the shouldInlineCss() method in your Mailable:

public function shouldInlineCss(): bool
{
    return $this->isProduction(); // Only inline in production
}

3. Customizing Inline Behavior

Configure via .env or config/mail-css-inliner.php:

MAIL_CSS_INLINER_ENABLED=true
MAIL_CSS_INLINER_EXCLUDE_CLASSES=admin-notification
MAIL_CSS_INLINER_REMOVE_STYLES=false

4. Integration with Blade Templates

Use @inlineCss directive in Blade emails:

@inlineCss
<style>
    .button { background: blue; }
</style>
<button class="button">Click</button>

5. Queueing and Inlining

The package works seamlessly with Laravel's queue system. CSS is inlined before the email is queued or sent.


Advanced Patterns

1. Dynamic CSS Inlining

Pass dynamic HTML to the facade and inline it on-the-fly:

$dynamicHtml = view('emails.dynamic', ['data' => $data])->render();
$inlinedHtml = MailCssInliner::inline($dynamicHtml);

2. Preserving Critical Styles

Use preserveStyles to keep specific styles intact:

MailCssInliner::inline($html, [
    'preserveStyles' => ['font-family', 'color'],
]);

3. Excluding Specific Emails

Skip inlining for certain mailables by overriding shouldInlineCss():

public function shouldInlineCss(): bool
{
    return !in_array($this->subject, ['Newsletter', 'Digest']);
}

4. Testing Inlined Emails

Mock the inliner in tests:

$this->app->shouldReceive('make')
    ->with('Fedeisas\MailCssInliner\MailCssInliner')
    ->andReturn(new class {
        public function inline($html) { return $html; } // No-op
    });

5. Customizing the Inliner Instance

Bind a custom inliner in AppServiceProvider:

$this->app->bind('Fedeisas\MailCssInliner\MailCssInliner', function ($app) {
    return new CustomInliner($app['config']);
});

Gotchas and Tips

Pitfalls

1. Performance Overhead

  • Issue: Inlining CSS adds processing time. For high-volume emails, this may impact queue performance.
  • Fix: Disable inlining for non-critical emails or use a queue worker with higher memory limits.

2. Broken Layouts

  • Issue: Some email clients (e.g., Outlook) may render inlined CSS unpredictably.
  • Fix: Test emails in multiple clients (Litmus, Email on Acid) and use !important sparingly.

3. Dynamic Content Issues

  • Issue: If your HTML is generated dynamically (e.g., with JavaScript), CSS inlining may fail.
  • Fix: Ensure HTML is fully rendered before inlining or use the facade manually.

4. Config Overrides

  • Issue: .env settings may not reflect changes immediately due to Laravel's caching.
  • Fix: Clear config cache:
    php artisan config:clear
    

5. Media Queries

  • Issue: Media queries in <style> tags may not inline correctly.
  • Fix: Move media queries to <link> tags or use the preserveStyles option.

Debugging Tips

1. Log Inlined HTML

Add this to your Mailable to debug:

protected function getHtmlContent()
{
    $html = parent::getHtmlContent();
    \Log::debug('Inlined HTML:', ['html' => $html]);
    return $html;
}

2. Check for Malformed HTML

  • Use a validator like HTML Tidy to clean HTML before inlining.
  • Example:
    $html = tidy($html, ['indent' => true, 'wrap' => 256]);
    

3. Exclude Problematic Classes

Add classes to MAIL_CSS_INLINER_EXCLUDE_CLASSES in .env:

MAIL_CSS_INLINER_EXCLUDE_CLASSES=problem-class,another-issue

4. Verify PHP Version

  • Ensure PHP 8.0+ is used (required for Laravel 9+ compatibility).
  • Check with:
    php -v
    

5. Clear Cached Views

If emails appear unchanged after config updates:

php artisan view:clear

Extension Points

1. Custom Inliner Logic

Extend the MailCssInliner class:

namespace App\Services;

use Fedeisas\MailCssInliner\MailCssInliner as BaseInliner;

class CustomInliner extends BaseInliner
{
    protected function shouldInlineStyle($selector)
    {
        // Custom logic to filter styles
        return parent::shouldInlineStyle($selector) && !str_contains($selector, 'no-inline');
    }
}

Bind it in AppServiceProvider:

$this->app->bind('Fedeisas\MailCssInliner\MailCssInliner', function ($app) {
    return new CustomInliner($app['config']);
});

2. Pre/Post-Processing Hooks

Use Laravel's Mail event listeners to modify HTML before inlining:

Mail::send(function ($m) {
    $m->to('user@example.com');
    $m->subject('Test');
    $m->html(view('emails.test'));
})->after(function ($message) {
    if ($message->hasTo('user@example.com')) {
        $message->html = MailCssInliner::inline($message->html);
    }
});

3. Integrate with Mailable Events

Listen to Creating event to conditionally inline:

use Illuminate\Mail\Events\MessageSending;

event(new MessageSending($message));
// Access $message->html and modify before sending

4. Add Custom CSS Rules

Inject additional styles before inlining:

$html = '<style>body { font-family: Arial; }</style>' . $html;
$inlinedHtml = MailCssInliner::inline($html);

5. Support for Dark Mode

Use media queries in <style> tags and preserve them:

MailCssInliner::inline($html, [
    'preserveStyles' => ['@media (prefers-color-scheme: dark)'],
]);
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.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver