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

stayallive/laravel-mail-css-inliner

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require stayallive/laravel-mail-css-inliner
    

    The package auto-registers via Laravel’s service provider discovery—no manual configuration required.

  2. First Use Case: Send an email with embedded CSS (e.g., <style> tags or <link> references) in your Blade template:

    Mail::to('user@example.com')->send(new AppMail());
    

    The package automatically inlines CSS during SwiftMailer’s rendering phase. No additional code needed.

  3. Where to Look First:

    • Service Provider: Stayallive\MailCssInliner\MailCssInlinerServiceProvider (handles SwiftMailer plugin registration).
    • SwiftMailer Plugin: Stayallive\MailCssInliner\SwiftMailer\CssInlinerPlugin (core inlining logic).
    • Config: None required, but you can publish the config for customization:
      php artisan vendor:publish --provider="Stayallive\MailCssInliner\MailCssInlinerServiceProvider"
      

Implementation Patterns

Workflows

  1. Default Inlining:

    • Trigger: Automatically inlines CSS for all emails sent via Laravel’s Mail facade or SwiftMailer directly.
    • Example:
      <!-- Before -->
      <style>
          .button { background: #000; color: #fff; }
      </style>
      <button class="button">Click</button>
      
      <!-- After (inlined) -->
      <button style="background: #000; color: #fff;">Click</button>
      
  2. Conditional Inlining:

    • Use the inlineCss() method on SwiftMailer’s Message object to manually control inlining:
      $message = (new \Swift_Message())
          ->setBody($html, 'text/html')
          ->inlineCss(); // Explicitly inline CSS
      
  3. Excluding Specific Emails:

    • Skip inlining for certain emails by setting a header:
      $message->getHeaders()->addTextHeader('X-Mail-Css-Inliner', 'false');
      
  4. Customizing Inlined Styles:

    • Publish the config and modify css_inliner.php to:
      • Whitelist/blacklist CSS properties (e.g., ['allowed_properties' => ['font-size', 'color']]).
      • Adjust media query handling or URL resolution.
  5. Integration with Mailable Classes:

    • Extend Mailable to add custom logic:
      public function build()
      {
          $this->withSwiftMessage(function ($message) {
              if ($this->shouldInlineCss()) {
                  $message->inlineCss();
              }
          });
      }
      
  6. Testing:

    • Mock the SwiftMailer plugin in tests:
      $plugin = new \Stayallive\MailCssInliner\SwiftMailer\CssInlinerPlugin();
      $transport = new \Swift_Transport_Memory();
      $mailer = new \Swift_Mailer($transport);
      $mailer->registerPlugin($plugin);
      

Integration Tips

  • Queue Delayed Emails: Inlining occurs at send time, so queued emails will still inline CSS when processed.
  • Markdown Emails: Works seamlessly with Laravel’s Markdown mailer (CSS in Markdown files is inlined).
  • Dynamic CSS: If CSS is generated dynamically (e.g., via JavaScript), ensure it’s embedded in the HTML before sending.

Gotchas and Tips

Pitfalls

  1. Performance Overhead:

    • Inlining CSS adds processing time. For high-volume emails, consider:
      • Caching inlined templates (e.g., store inlined HTML in Redis).
      • Disabling inlining for non-critical emails (e.g., transactional emails with minimal styling).
  2. CSS Specificity Issues:

    • Inlined styles may override external styles unexpectedly. Test edge cases like:
      /* External */
      .button { color: red !important; }
      /* Inlined */
      <button style="color: blue;">Click</button>
      
      Result: blue wins due to !important in external CSS. Use the allowed_properties config to restrict !important.
  3. Media Queries:

    • By default, media queries (e.g., @media screen) are stripped. To preserve them:
      // In config/css_inliner.php
      'preserve_media_queries' => true,
      
  4. URL Resolution:

    • External CSS files (e.g., <link href="css/styles.css">) must be accessible during inlining. Use absolute URLs or ensure the file is publicly available.
  5. SwiftMailer Version Conflicts:

    • The package targets Laravel’s bundled SwiftMailer. If using a custom version, ensure compatibility:
      composer require swiftmailer/swiftmailer:^6.0
      
  6. Debugging Inlined Output:

    • Inspect the final HTML by logging the SwiftMailer Message body:
      $message->setBody($html)->inlineCss();
      \Log::debug($message->getBody());
      

Tips

  1. Custom Inliner Logic:

    • Extend the plugin by binding a custom inliner to the container:
      $this->app->bind(\Stayallive\MailCssInliner\Contracts\CssInliner::class, function () {
          return new CustomCssInliner();
      });
      
  2. Whitelisting Properties:

    • Restrict inlined properties to security-critical emails:
      // config/css_inliner.php
      'allowed_properties' => ['color', 'font-size', 'font-weight'],
      
  3. Fallback for Broken Emails:

    • Use the fallback_css config to inject default styles if inlining fails:
      'fallback_css' => '<style>.fallback { color: #000; }</style>',
      
  4. Testing Edge Cases:

    • Test with:
      • Nested <style> tags.
      • CSS variables (e.g., --primary-color).
      • Dynamic classes (e.g., class="btn btn--primary").
  5. Monitoring:

    • Track inlining failures by logging exceptions in the plugin’s inlineCss method:
      try {
          $this->inliner->inline($message);
      } catch (\Exception $e) {
          \Log::error("CSS inlining failed: " . $e->getMessage());
      }
      
  6. Performance Tuning:

    • Disable inlining for non-HTML emails (e.g., plaintext):
      if ($message->isHtmlPart()) {
          $message->inlineCss();
      }
      
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope