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 Newsletter Laravel Package

spatie/laravel-newsletter

Integrate newsletter subscriptions in Laravel with a simple API. Supports Mailcoach and Mailchimp, lets you manage lists, subscribe/unsubscribe users, and configure drivers via a published config file.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-newsletter
    

    Publish the config file:

    php artisan vendor:publish --provider="Spatie\Newsletter\NewsletterServiceProvider" --tag="config"
    
  2. Configuration: Edit config/newsletter.php to define your email service (Mailcoach/MailChimp) and API keys.

  3. First Use Case: Subscribe a user to a list:

    use Spatie\Newsletter\Newsletter;
    
    Newsletter::subscribe('mailcoach', 'list-id', 'user@example.com');
    

Key Files to Review

  • config/newsletter.php – Service configurations.
  • app/Providers/NewsletterServiceProvider.php – Service binding overrides.
  • vendor/spatie/laravel-newsletter/src/ – Core logic (for advanced use).

Implementation Patterns

Core Workflows

  1. Subscribing Users:

    // Single email
    Newsletter::subscribe('mailcoach', 'list-uuid', 'user@example.com');
    
    // Multiple emails (batch)
    Newsletter::subscribe('mailcoach', 'list-uuid', ['a@example.com', 'b@example.com']);
    
    // With metadata (Mailchimp only)
    Newsletter::subscribe('mailchimp', 'list-id', 'user@example.com', [
        'FNAME' => 'John',
        'LNAME' => 'Doe',
    ]);
    
  2. Unsubscribing:

    Newsletter::unsubscribe('mailcoach', 'list-uuid', 'user@example.com');
    
  3. Checking Subscriptions:

    if (Newsletter::isSubscribed('mailcoach', 'list-uuid', 'user@example.com')) {
        // Handle logic
    }
    
  4. Syncing Subscribers:

    // Sync from a Laravel model (e.g., User)
    Newsletter::syncSubscribers('mailcoach', 'list-uuid', User::all()->pluck('email'));
    

Integration Tips

  • Laravel Events: Trigger subscriptions on user registration:

    // In UserObserver or Event
    event(new Registered($user));
    
    // In EventServiceProvider
    Registered::listen(function ($event) {
        Newsletter::subscribe('mailcoach', 'welcome-list', $event->user->email);
    });
    
  • Middleware: Restrict access to newsletter pages:

    public function handle(Request $request, Closure $next) {
        if (!Newsletter::isSubscribed('mailcoach', 'premium-list', $request->user()->email)) {
            abort(403);
        }
        return $next($request);
    }
    
  • API Endpoints: Expose subscription management via API:

    Route::post('/subscribe', function (Request $request) {
        Newsletter::subscribe('mailcoach', 'list-uuid', $request->email);
        return response()->json(['status' => 'subscribed']);
    });
    
  • Queue Jobs: Offload heavy syncs to queues:

    Newsletter::syncSubscribers('mailcoach', 'list-uuid', $emails)->onQueue('newsletters');
    

Gotchas and Tips

Pitfalls

  1. API Key Security:

    • Never commit config/newsletter.php to version control if it contains API keys.
    • Use Laravel’s .env for sensitive keys and add the config file to .gitignore.
  2. Rate Limits:

    • Mailchimp/Mailcoach have API rate limits. Batch operations (e.g., syncSubscribers) may fail if too large. Split into chunks:
      $emails->chunk(100)->each(function ($chunk) {
          Newsletter::subscribe('mailcoach', 'list-uuid', $chunk->all());
      });
      
  3. Duplicate Subscriptions:

    • Subscribing the same email multiple times may cause duplicates. Use isSubscribed() to check first:
      if (!Newsletter::isSubscribed('mailcoach', 'list-uuid', $email)) {
          Newsletter::subscribe('mailcoach', 'list-uuid', $email);
      }
      
  4. Mailcoach vs. Mailchimp Differences:

    • Mailcoach: Uses UUIDs for lists (list-uuid).
    • Mailchimp: Uses numeric IDs (list-id).
    • Metadata: Only Mailchimp supports custom merge tags (e.g., FNAME, LNAME).
  5. Webhook Handling:

    • Mailchimp/Mailcoach provide webhooks for subscription changes. Ensure your endpoint is secure and idempotent:
      Route::post('/mailchimp-webhook', [MailchimpWebhookController::class, 'handle']);
      
    • Validate webhook signatures (Mailchimp) to prevent spoofing.

Debugging Tips

  1. Enable Logging: Add to config/newsletter.php:

    'log' => env('NEWSLETTER_LOG', false),
    

    Check storage/logs/laravel.log for API errors.

  2. API Response Inspection: Use tap() to debug responses:

    $response = Newsletter::subscribe('mailcoach', 'list-uuid', 'user@example.com')->tap(function ($response) {
        \Log::info('Subscription response:', $response->toArray());
    });
    
  3. Testing: Use the Newsletter facade in tests with mocks:

    $this->partialMock(Newsletter::class, function ($mock) {
        $mock->shouldReceive('subscribe')
             ->once()
             ->with('mailcoach', 'list-uuid', 'user@example.com');
    });
    

Extension Points

  1. Custom Services: Extend the package to support other providers (e.g., Brevo, Klaviyo):

    // app/Providers/NewsletterServiceProvider.php
    $this->app->bind('newsletter.brevo', function () {
        return new BrevoService();
    });
    
  2. Event Listeners: Listen for subscription events:

    // In EventServiceProvider
    NewsletterSubscribed::listen(function ($event) {
        // Send welcome email, etc.
    });
    
  3. Model Observers: Automate subscriptions on model events:

    class UserObserver {
        public function created(User $user) {
            Newsletter::subscribe('mailcoach', 'welcome-list', $user->email);
        }
    }
    
  4. Custom Metadata: For Mailchimp, extend metadata handling:

    Newsletter::subscribe('mailchimp', 'list-id', 'user@example.com', [
        'custom_field_1' => 'value',
    ]);
    
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