Weave 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

a2zwebltd/laravel-newsletter

A Laravel package for managing newsletter subscriptions and mailing lists. It provides tools to subscribe, unsubscribe, and organize subscribers, integrating with your existing user model and database to simplify email list handling in Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

This package adds RFC 8058 one-click unsubscribe to a Laravel app: it registers a POST route named unsubscribe.one-click, wires the List-Unsubscribe / List-Unsubscribe-Post headers onto your mailables, and handles the tokenised request that Gmail and Yahoo fire when a recipient hits "Unsubscribe" in the inbox UI.

Minimum path to a working setup:

  1. Require the package and, on Laravel 13, pin ^1.3.1 — earlier versions return 419 to mail clients (see Gotchas).
  2. Publish the config (config/unsubscribe.php) and read it before touching anything else. The only knob most apps need is routes.enabled, which controls whether the package auto-registers the endpoint.
  3. Add the unsubscribe headers to your base mailable (or a trait/middleware applied to all outgoing mail). Both headers are required; List-Unsubscribe-Post: List-Unsubscribe=One-Click is what makes the POST route get used instead of a browser link.
  4. Send a real message to a Gmail account, open it, and use "Unsubscribe" from the message header. That is the only test that exercises the actual client behaviour.

First use case: transactional/marketing mail sent through a single base mailable class. Wire it once there and every subclass inherits compliance.

Implementation Patterns

Base mailable trait. Put header injection and token generation in a HasOneClickUnsubscribe trait applied to your base mailable, rather than per-mailable. Tokens should be signed (or hashed and stored) so the route can resolve the subscriber without an authenticated session — the mail client sends no cookies, no session, no CSRF token.

Keep the package route; don't re-declare it. routes.enabled => true is the low-maintenance default. The package owns the CSRF exclusion for you, and it now covers PreventRequestForgery as well as the two legacy middleware names.

Re-declaring the route (routes.enabled => false). Use this when you need custom resolution logic (multi-tenant, per-list preferences, soft-delete semantics). Mirror the package's middleware exclusions exactly:

Route::post('unsubscribe/one-click/{token}', OneClickController::class)
    ->name('unsubscribe.one-click')
    ->withoutMiddleware(array_filter([
        \Illuminate\Foundation\Http\Middleware\PreventRequestForgery::class, // Laravel 13
        \Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,    // Laravel 11/12
        \App\Http\Middleware\VerifyCsrfToken::class,
    ], fn ($m) => class_exists($m)));

The package ships an agent skill documenting this form — check it before hand-rolling the exclusion list on a Laravel 13 upgrade.

Idempotency and speed. Mail providers retry. Return 200 for "already unsubscribed" and "token unknown but well-formed" alike; only return 4xx for genuinely malformed tokens. Do the actual work (DB write, list sync to your ESP) in a queued job so the endpoint responds inside the provider's timeout.

Feature tests. Laravel's test suite disables CSRF middleware by default, so a passing test proves nothing about the 419 class of bugs. Add one test that asserts the exclusion explicitly — either by asserting the route's gatherMiddleware() no longer contains the CSRF class, or by hitting the route with the middleware stack enabled.

Compliance surface. Pair one-click with a human-facing GET preference-centre page and honour the unsubscribe immediately for marketing mail (transactional exemptions are narrow and jurisdiction-specific).

Gotchas and Tips

  • 419 to mail clients is the signature failure of this package. It means the request reached your app and was rejected by CSRF, not that the token was bad. Log the response status of the endpoint in production; a 419 spike is invisible to users and silently non-compliant.
  • Exclusions are matched by the exact class registered on the middleware group. Laravel 13 renamed the web group's CSRF middleware to PreventRequestForgery, with ValidateCsrfToken/VerifyCsrfToken retained as subclasses. Excluding the subclass does not remove the parent, which is why v1.3.1 adds the new class name. If you re-declare the route and are on Laravel 13, you must exclude PreventRequestForgery too.
  • Laravel 11 and 12 are unchanged — the fix is guarded, so no action needed there. But auditing your own middleware stack for other web-group additions (rate limiting, AuthenticateSession, custom CSRF variants) is worthwhile: any middleware added to web after the package's exclusion list was written becomes a potential 419.
  • Don't put the route behind auth or verified. Mail clients have no session. The signed token is the credential; make it single-purpose and expiring if your threat model requires it.
  • Test with a real client at least once per release. Curl-ing the endpoint with the right headers proves the app works, not that Gmail accepts your List-Unsubscribe URL (it must be https, publicly reachable, and stable across sends).
  • Extension point: the package resolves the subscriber from the token; if you need per-category preferences (product updates vs. announcements), the cleanest approach is to encode the category in the signed token payload rather than adding query strings, which some clients strip.
  • Upgrade note: if you pinned 1.3.0 or earlier and run Laravel 13, treat this as a required patch, not optional — the endpoint is effectively broken until you upgrade or manually exclude the new middleware class.
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.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox