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.
Installation:
composer require spatie/laravel-newsletter
Publish the config file:
php artisan vendor:publish --provider="Spatie\Newsletter\NewsletterServiceProvider" --tag="config"
Configuration:
Edit config/newsletter.php to define your email service (Mailcoach/MailChimp) and API keys.
First Use Case: Subscribe a user to a list:
use Spatie\Newsletter\Newsletter;
Newsletter::subscribe('mailcoach', 'list-id', 'user@example.com');
config/newsletter.php – Service configurations.app/Providers/NewsletterServiceProvider.php – Service binding overrides.vendor/spatie/laravel-newsletter/src/ – Core logic (for advanced use).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',
]);
Unsubscribing:
Newsletter::unsubscribe('mailcoach', 'list-uuid', 'user@example.com');
Checking Subscriptions:
if (Newsletter::isSubscribed('mailcoach', 'list-uuid', 'user@example.com')) {
// Handle logic
}
Syncing Subscribers:
// Sync from a Laravel model (e.g., User)
Newsletter::syncSubscribers('mailcoach', 'list-uuid', User::all()->pluck('email'));
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');
API Key Security:
config/newsletter.php to version control if it contains API keys..env for sensitive keys and add the config file to .gitignore.Rate Limits:
syncSubscribers) may fail if too large. Split into chunks:
$emails->chunk(100)->each(function ($chunk) {
Newsletter::subscribe('mailcoach', 'list-uuid', $chunk->all());
});
Duplicate Subscriptions:
isSubscribed() to check first:
if (!Newsletter::isSubscribed('mailcoach', 'list-uuid', $email)) {
Newsletter::subscribe('mailcoach', 'list-uuid', $email);
}
Mailcoach vs. Mailchimp Differences:
list-uuid).list-id).FNAME, LNAME).Webhook Handling:
Route::post('/mailchimp-webhook', [MailchimpWebhookController::class, 'handle']);
Enable Logging:
Add to config/newsletter.php:
'log' => env('NEWSLETTER_LOG', false),
Check storage/logs/laravel.log for API errors.
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());
});
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');
});
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();
});
Event Listeners: Listen for subscription events:
// In EventServiceProvider
NewsletterSubscribed::listen(function ($event) {
// Send welcome email, etc.
});
Model Observers: Automate subscriptions on model events:
class UserObserver {
public function created(User $user) {
Newsletter::subscribe('mailcoach', 'welcome-list', $user->email);
}
}
Custom Metadata: For Mailchimp, extend metadata handling:
Newsletter::subscribe('mailchimp', 'list-id', 'user@example.com', [
'custom_field_1' => 'value',
]);
How can I help you explore Laravel packages today?