sammyjo20/wagonwheel
Wagonwheel is an open-source Laravel package by Sammy Jo that provides a clean, developer-friendly API for adding practical functionality to Laravel applications. It installs easily, follows Laravel conventions, and helps keep your codebase simple and maintainable.
What the package does: Wagonwheel hooks into Laravel's mail pipeline, persists the fully rendered HTML body of each outgoing email, and exposes a public route keyed by a unique identifier so a recipient can click "view this email in your browser." It is effectively a storage-and-retrieval shim around Laravel's Mail subsystem — it does not replace the mailer, templates, or transport.
Architecture fit: Conceptually this is a clean fit. It operates at the mail-send boundary as a listener/decorator, so it should not require changes to business logic or Mailable definitions beyond a small integration surface (trait, config, or Blade helper). Blast radius is contained: the persistence and routing layers are additive, and the feature can be feature-flagged and removed without touching domain code. The conceptual pattern — capture rendered output, serve it from a signed or unguessable URL — is sound and is what ESPs do internally.
Integration feasibility: Mechanically simple. Composer install, publish config and migration, register the trait or listener, add the link to the email template. Realistic effort is days for a spike, one to two sprints to productionize with tests, retention, and access controls. The binding constraint is version compatibility, not complexity.
Technical risk: This is where the package fails as a candidate for direct adoption.
MessageSending listener and the write throws, mail delivery can fail or degrade. Email is business-critical; a decorative "view in browser" feature must never be able to block a transaction or notification.Key questions to resolve before a decision:
Stack fit: Appropriate only if we are on a Laravel 6–8 era application (or are willing to fork). The package is a peer dependency at the mail layer, so it fits any Laravel app's architecture; the mismatch is version and maintenance, not design.
Migration path: Treat it as a reference implementation, not a dependency. Two viable paths:
MessageSending, serialize rendered HTML to an email_archive table with uuid, mailable, created_at, and a expires_at, expose a route behind signed middleware plus an optional auth guard, and add a scheduler job to prune. This gives us control over PII handling, retention, and delivery safety, and removes the archived-dependency conversation entirely.Compatibility work required regardless of path:
terminable middleware so it never blocks or breaks a send.URL::temporarySignedRoute and a short TTL.to, cc, headers, or attachments unless required.Sequencing:
Maintenance: An archived, single-maintainer package in 2021 is a permanent liability. Composer security advisories will eventually flag it, or the code will silently rot against framework upgrades. Either outcome converts a "free" package into a recurring maintenance line item. Budget for ownership explicitly; do not treat the MIT license as zero-cost.
Support: No upstream support, no CVE response, no compatibility fixes. Internal on-call becomes the only escalation path. For a customer-facing email feature, that is an acceptable trade only for a small, well-understood codebase — which this is, which is why a fork or reimplementation is tractable.
Scaling: The real cost driver is storage, not compute. Every transactional email becomes a row with a full HTML body; a system sending 100k emails/month generates meaningful table growth and backup bloat. Mitigations: aggressive retention (7–30 days), partitioning or TTL cleanup job, and excluding high-volume or low-value mail classes. Read traffic is spiky but low — email clients and users hitting the link are a rounding error next to send volume. Serving is cheap; storing is not.
Failure modes:
Ramp-up: Engineering ramp-up is low — a mid-level Laravel developer can read the entire package in an afternoon, and the pattern is well understood by anyone who has worked with ESP-hosted email. The ramp-up cost is organizational, not technical: security review for PII storage, legal sign-off on retention, and an explicit decision on who maintains the fork. Expect those conversations to take longer than the code.
Bottom line: The pattern is worth adopting; the package is not. The 2021 archive date, absent modern framework support, and PII storage implications make direct dependency a poor trade for a feature this small. Recommend a short internal build (or a tightly scoped fork) using Wagonwheel as design reference, gated behind a feature flag, with signed URLs, queued non-blocking persistence, and a hard retention window.
How can I help you explore Laravel packages today?