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

Cssinliner Extra Laravel Package

twig/cssinliner-extra

Twig CssInliner Extension adds the inline_css filter to Twig templates, letting you inline CSS into HTML output. Useful for building email-friendly HTML with styles converted to inline attributes during rendering.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package Add to composer.json:

    "require": {
        "twig/cssinliner-extra": "^3.24"
    }
    

    Run:

    composer require twig/cssinliner-extra
    
  2. Register the Twig Extension In your AppServiceProvider or a dedicated Twig service provider:

    use Twig\Extension\CssInlinerExtraExtension;
    
    public function register()
    {
        $this->app->singleton(Twig\Extension\CssInlinerExtraExtension::class);
    }
    
    public function boot()
    {
        $this->app->make(Twig\Extension\CssInlinerExtraExtension::class)
            ->register($this->app->make('twig'));
    }
    
  3. First Use Case: Inline CSS in a Twig Template

    {# resources/views/emails/welcome.twig #}
    <div class="email-container">
        <h1>Welcome!</h1>
        <p>This is a test email.</p>
    </div>
    <style>
        .email-container { font-family: Arial; padding: 20px; }
        h1 { color: #333; }
    </style>
    
    {# Inline the CSS #}
    {{ include('emails/welcome.twig') | inline_css }}
    

Where to Look First

  • Twig Filter Documentation: Twig inline_css Filter
  • Package Source: GitHub Repository
  • Configuration Options: Check CssInlinerExtraExtension for customization (e.g., remote flag for external CSS).

Implementation Patterns

Core Workflows

  1. Basic Inlining in Twig Templates

    {{ content_with_styles | inline_css }}
    
    • Works for both embedded <style> tags and external CSS (if remote: true is configured).
  2. Build-Time Processing with Artisan Create a custom Artisan command to pre-process emails:

    // app/Console/Commands/InlineEmailCss.php
    namespace App\Console\Commands;
    
    use Illuminate\Console\Command;
    use Twig\Environment;
    use Twig\Extension\CssInlinerExtraExtension;
    
    class InlineEmailCss extends Command
    {
        protected $signature = 'emails:inline-css
            {--templates= : Path to template directory}
            {--output= : Output directory for processed emails}';
    
        public function handle(Environment $twig, CssInlinerExtraExtension $extension)
        {
            $templates = $this->option('templates');
            $outputDir = $this->option('output');
    
            // Load and process each template
            foreach (glob($templates . '/*.twig') as $template) {
                $content = file_get_contents($template);
                $inlined = $twig->createTemplate($content)
                    ->renderBlock('body', [], ['inline_css' => true]);
                file_put_contents($outputDir . '/' . basename($template, '.twig') . '.html', $inlined);
            }
        }
    }
    

    Run:

    php artisan emails:inline-css --templates=resources/views/emails --output=public/emails
    
  3. Component-Driven Email Design Use Twig partials with embedded CSS:

    {# resources/views/emails/partials/header.twig #}
    <div class="header">
        <img src="{{ logo_url }}" alt="Logo">
    </div>
    <style>
        .header { background: #f5f5f5; padding: 20px; }
    </style>
    
    {# resources/views/emails/welcome.twig #}
    {{ include('emails/partials/header.twig') | inline_css }}
    <div class="content">
        {{ include('emails/partials/content.twig') | inline_css }}
    </div>
    

Integration Tips

  • Laravel Mailables: Combine with Laravel’s Mailable classes for dynamic emails:

    // app/Mail/WelcomeEmail.php
    public function build()
    {
        return $this->markdown('emails.welcome')
                    ->with([
                        'logo_url' => asset('images/logo.png'),
                    ]);
    }
    

    Ensure the Twig template uses the inline_css filter.

  • Caching Inlined Emails: Cache processed emails to avoid runtime overhead:

    $inlinedEmail = Cache::remember(
        "email_{$user->id}_welcome_inlined",
        now()->addHours(1),
        fn() => $twig->createTemplate($content)->renderBlock('body', [], ['inline_css' => true])
    );
    
  • Testing: Use Laravel’s MailFake to test inlined emails:

    $this->mail->assertSent(WelcomeEmail::class, function ($mail) {
        return str_contains($mail->html, 'style="font-family: Arial;"');
    });
    

Gotchas and Tips

Pitfalls

  1. Silent CSS Dropping

    • The package silently drops unsupported CSS selectors (e.g., @media, :hover, combinators like div > p).
    • Fix: Test templates early and provide fallbacks:
      {# Fallback for unsupported selectors #}
      <style>
          @media (max-width: 600px) {
              /* This will be dropped; add inline styles as fallback */
              .content { font-size: 14px !important; }
          }
      </style>
      
  2. Remote CSS Risks

    • Enabling remote: true (to fetch external CSS) introduces XSS risks if input isn’t sanitized.
    • Fix: Disable remote by default and sanitize all dynamic content:
      // In your Twig extension config
      $extension->setRemote(false);
      
  3. Performance Overhead

    • Runtime inlining is CPU-intensive. High-volume email sends may cause timeouts.
    • Fix: Use build-time processing or caching:
      php artisan emails:inline-css --templates=resources/views/emails --output=storage/emails
      
  4. Twig-Specific Quirks

    • The filter only works in Twig templates. Blade templates require a workaround (e.g., pre-processing).
    • Fix: Avoid mixing Blade and Twig for emails. Stick to Twig if using this package.
  5. Selector Specificity Conflicts

    • Inlined styles may override existing styles due to specificity.
    • Fix: Use !important sparingly or adjust your CSS to avoid conflicts.

Debugging Tips

  1. Inspect Inlined Output Use Twig’s dump filter to debug:

    {{ content | inline_css | raw | dump }}
    
  2. Check for Dropped Selectors Compare the output with the original CSS to identify missing styles.

  3. Log Warnings Extend the package to log dropped selectors:

    // In your Twig extension
    $inliner->setLogger(function ($message) {
        \Log::warning('CSS Inliner: ' . $message);
    });
    

Extension Points

  1. Custom Inliner Configuration Override the default CssInliner behavior:

    $inliner = new \Twig\Extension\CssInlinerExtraExtension\CssInliner([
        'preserve_media_queries' => false, // Default is false
        'preserve_pseudo_elements' => false, // Default is false
    ]);
    
  2. Pre/Post-Processing Hook into the inlining process to modify output:

    $extension->setPostProcessor(function ($html) {
        return str_replace('class="old-class"', 'class="new-class"', $html);
    });
    
  3. Fork and Maintain Given the package’s abandoned state, fork it on GitHub and:

    • Add tests for critical selectors.
    • Implement missing features (e.g., better media query support).
    • Monitor upstream changes and merge selectively.

Laravel-Specific Tips

  1. Queue Inlining for Dynamic Emails Use Laravel Queues to avoid timeouts:

    // In your Mailable
    public function build()
    {
        return $this->markdown('emails.welcome')
            ->with(['content' => $this->content])
            ->queueOn('emails');
    }
    
  2. Use View Composers Automatically inline CSS for all email templates:

    // app/View/Composers/EmailComposer.php
    public function compose($view, array $data)
    {
        if (str_starts_with($view, 'emails.')) {
            $data['content'] = $view->render() | inline_css;
        }
    }
    
  3. **Environment

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