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

jeffersongoncalves/laravel-mail

Complete email management for Laravel: logging, translated database templates with versioning, webhook delivery tracking for five providers, pixel open/click tracking, suppression lists, inline CSS, statistics, and retries.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Highly Complementary to Laravel Ecosystem: The package is designed specifically for Laravel, leveraging its native Mail facade, Notification system, and Event system. It integrates seamlessly with Laravel’s existing email infrastructure (e.g., Mailable, Notification channels) without requiring architectural overhauls.
  • Modular Design: Features like template management, tracking, suppression lists, and now campaign reporting are decoupled, allowing selective adoption (e.g., use only logging or only pixel tracking). Campaign reporting is gated behind laravel-mail.campaigns.enabled, so it can be evaluated independently.
  • Database-Centric: Relies on Laravel’s Eloquent ORM and migrations, fitting well with applications using relational databases (MySQL, PostgreSQL, etc.). The schema is well-defined and versioned. v1.4.0 adds a new add_tags_to_mail_logs_table migration, extending the existing mail_logs table rather than introducing a parallel schema — a low-coupling change that keeps the aggregate reporting model on the same table.
  • Event-Driven: Leverages Laravel’s event system for extensibility (e.g., MailBounced, MailOpened), enabling custom logic without modifying core package code.
  • Campaign Attribution via Tags: As of 1.4.0, mail tags (tag() / Envelope tags) are persisted on the log record, creating a lightweight attribution key. CampaignReport and php artisan mail:campaign [tag] then aggregate sent, delivered, bounced, complained, distinct opens/clicks, open/click/click-to-open rates, and most-clicked links per campaign. This is a read-model layered on top of existing tracking data — no external analytics dependency required for baseline campaign reporting.

Integration Feasibility

  • Low Friction for Laravel Apps: Requires minimal setup (composer install, migrations, config publishing). No breaking changes to existing email workflows if logging is disabled. Upgrading from 1.3.x to 1.4.0 is additive: one new migration and one new config block, with campaign features off by default.
  • Provider Agnostic: Supports multiple email providers (SES, SendGrid, etc.) via webhooks or pixel tracking, reducing vendor lock-in. Campaign report accuracy inherits the accuracy of the underlying signal (webhook vs. pixel), so mixed-provider estates will produce mixed-fidelity campaign metrics.
  • Template System: Replaces traditional Blade-based emails with a database-driven system, which may require refactoring existing email templates but offers long-term flexibility (e.g., multi-language support, versioning). 1.4.0 fixes template text bodies so they are set directly on the message rather than passed to text() as a view name — a correctness fix that unblocks plain-text parts for template-driven mail, but one that should be regression-tested if you ship text alternatives.
  • Compatibility:
    • Laravel Version: Explicitly supports Laravel 10+ (based on last release date). Test compatibility with your Laravel version.
    • PHP Version: Requires PHP 8.1+ (aligns with Laravel 10’s requirements).
    • Dependencies: Uses spatie/laravel-translatable (for templates) and tijsverkoyen/css-to-inline-styles (for CSS inlining), both well-maintained packages. No new dependencies appear to be introduced by the campaign reporting feature.

Technical Risk

  • Database Schema Changes: Introduces 6+ tables (mail_logs, mail_templates, mail_template_versions, etc.), plus the 1.4.0 migration adding a tags column to mail_logs. On a large existing mail_logs table, verify the migration is online-safe (column addition + any index build can lock or degrade writes depending on engine/version). Plan a maintenance window or use an online-DDL tool if the table is already tens of millions of rows.
  • Tag Cardinality and Query Cost: Campaign reports aggregate over mail_logs filtered by tag. Without an index on the tags column (and a sensible tag taxonomy), report queries will table-scan and degrade as volume grows. Treat tag naming as a governed convention, not free-form strings, or reports become unjoinable.
  • Webhook Reliability: Webhook-based tracking depends on provider uptime and network connectivity. Pixel tracking is more resilient but may have lower accuracy (e.g., blocked images, ad blockers). Because campaign rates (open/click/click-to-open) are derived from these signals, campaign reporting inherits their noise — particularly Apple Mail Privacy Protection–style prefetch inflation of open rates.
  • Performance Overhead:
    • Logging: Every email generates a database record, now with tag payload. For high-volume senders, consider batching or async logging (e.g., queue jobs).
    • Pixel Tracking: Injects tracking pixels/rewrites links, which may impact email rendering in some clients (e.g., Outlook’s "block images" setting).
    • CSS Inlining: Can increase email size and processing time for large templates.
    • Reporting: mail:campaign runs ad hoc aggregate queries; running it against production during peak send windows may contend with write traffic. Prefer read replicas or scheduled off-peak execution.
  • Multi-Tenancy: If your app is multi-tenant, ensure the package’s tenant-scoping feature is configured correctly to avoid data leakage. Campaign reports are tag-scoped, not tenant-scoped — a tag reused across tenants would blend their metrics. Enforce tenant-qualified tags.
  • Customization Limits: While extensible, deep customization (e.g., overriding core models, or extending CampaignReport with custom metrics) may require forking the package.

Key Questions

  1. Volume and Scale:
    • How many emails are sent daily? Will logging/tracking tables grow uncontrollably?
    • Are there plans to implement async logging or pruning strategies?
    • What is the current row count of mail_logs, and how long will the 1.4.0 tags migration take to apply in production?
  2. Provider Dependencies:
    • Which email providers are used? Are webhooks feasible for all, or will pixel tracking be the primary method?
    • Are there SLAs for webhook reliability from providers (e.g., SendGrid’s 24-hour retry window)?
  3. Template Migration:
    • How many existing Blade-based emails need to be converted to database templates? What’s the effort to backfill historical templates?
    • Do any templates ship plain-text alternatives that were affected by the pre-1.4.0 text() bug, and do those need re-validation?
  4. Campaign Tag Strategy (new in 1.4.0):
    • What is the tag taxonomy (product area, tenant, lifecycle stage)? Who owns naming and prevents collisions?
    • Which reports do stakeholders actually need — the built-in mail:campaign output, or export into an existing BI/data warehouse?
    • Do we need historical campaign metrics for mail sent before tags existed? (Retroactive attribution is not possible; only newly tagged sends are reportable.)
  5. Compliance:
    • Does the List-Unsubscribe header meet regulatory requirements (e.g., CAN-SPAM, GDPR)?
    • Are there legal implications for pixel tracking (e.g., user consent for tracking), and do campaign open/click reports constitute behavioral profiling under our privacy policy?
  6. Monitoring:
    • How will tracking events (opens, clicks, bounces) be monitored/alerted on? Are there existing dashboards or will new ones be built?
    • Should campaign rates feed alerting (e.g., bounce-rate thresholds triggering send pause)?
  7. Fallbacks:
    • What’s the fallback for when webhooks fail or pixel tracking is blocked? (e.g., manual reconciliation)
    • What is the authoritative source when provider dashboard counts disagree with CampaignReport?
  8. Testing:
    • How will email templates and tracking be tested? (e.g., staging environments for webhook testing, mock pixels for click tracking).
    • How will campaign report correctness be validated (fixture data set with known sent/opened/clicked counts)?

Integration Approach

Stack Fit

  • Laravel Core: Fully compatible with Laravel’s Mail, Notification, and Event systems. No conflicts with existing email infrastructure. Campaign reporting consumes existing log/tracking data through Eloquent aggregates and an artisan command — no new runtime service required.
  • Database: Optimized for PostgreSQL/MySQL. Avoid SQLite if using webhook tracking (requires HTTP endpoints). Confirm index coverage on the new tags column before enabling campaigns.enabled in production.
  • Queue System: If using Laravel Queues, email logging can be offloaded to async jobs to reduce latency.
  • Caching: Template translations and layouts can be cached (e.g., Redis) to improve performance. Campaign report results are a candidate for scheduled materialization if queried frequently by stakeholders.
  • Frontend: Pixel tracking requires no frontend changes; click tracking rewrites URLs server-side. Campaign reports surface via CLI today; any stakeholder-facing UI is ours to build on top of CampaignReport.
  • Scheduling: Register mail:campaign (or a custom job wrapping CampaignReport) on the scheduler to snapshot metrics over time, since the command computes point-in-time aggregates.

Migration Path

  1. Phase 1: Logging and Templates (Low Risk)

    • Install the package and publish migrations/config.
    • Enable logging (LARAVEL_MAIL_LOGGING_ENABLED=true) to audit existing emails without disrupting workflows.
    • Migrate 1–2 critical Blade emails to database templates. Use the PreviewTemplateAction to validate rendering before sending. Validate plain-text parts explicitly, given the 1.4.0 text() behavior change.
    • Gradually replace Blade emails with TemplateMailable classes.
  2. Phase 1b: Upgrade to 1.4.0 (Low Risk, Additive)

    • Publish and run the add_tags_to_mail_logs_table migration in a staging clone sized like production to measure runtime.
    • Leave laravel-mail.campaigns.enabled off until tag conventions are agreed; the feature is inert when disabled.
    • Regression-test any template with a text body.
  3. Phase 2: Tracking (Medium Risk)

    • Configure webhooks for primary email providers (e.g., SendGrid). Test locally using tools like SendGrid’s webhook simulator.
    • Fall back to pixel tracking for providers without webhook support or during webhook outages.
    • Implement listeners for MailBounced/MailComplained to auto-suppress addresses and trigger alerts.
  4. Phase 3: Campaign Reporting (Medium Risk, 1.4.0)

    • Define and document the tag taxonomy; add tag() calls to outbound mail at the point of send (job/notification layer), not scattered across templates.
    • Enable laravel-mail.campaigns.enabled, run php artisan mail:campaign [tag] on a known campaign, and reconcile against provider dashboards before publishing any number.
    • Decide whether reports stay CLI-only or get exported to a warehouse/BI tool; schedule snapshots if trend lines are needed.
  5. Phase 4: Advanced Features (High Customization)

    • Enable inline CSS and List-Unsubscribe headers globally.
    • Set up pruning (php artisan mail:prune) for log cleanup — noting pruning truncates the historical window available to campaign reports.
    • Integrate with analytics tools (e.g., export tracking data to a data warehouse).

Compatibility

  • Existing Mailables: Can coexist with traditional Mailable classes. Only TemplateMailable classes benefit from full template features.
  • Upgrade 1.3.0 → 1.4.0: Additive release. New migration + new config key + new command/class. The only behavioral change is the template text-body fix; no deprecations called out in the notes. Standard upgrade path: composer update, php artisan migrate, republish config to pick up the campaigns block.
  • Tag Propagation: Tags set via tag() or Envelope tags are now read by the package. If you already set tags for provider-side purposes (e.g., SendGrid categories), those will now appear in mail_logs — verify naming and volume are acceptable and that no sensitive values leak into tag strings.
  • Third-Party Packages: No known conflicts with popular Laravel packages (e.g., spatie/laravel-activitylog, laravel-notification-channels). Test with your stack.
  • Legacy Systems: If using non-Laravel email systems (e.g., direct SMTP), pixel tracking can still be used, but webhook tracking will be limited — and campaign reports will be blind to that traffic entirely.

Sequencing

Step Priority Effort Dependencies
Install and configure package High Low Laravel 10+
Enable logging and validate data High Medium Database
Run 1.4.0 tags migration (staging then prod) High Low DBA review for large tables
Regression-test template text bodies High Low Templates with text parts
Define campaign tag taxonomy Medium Medium Marketing/product alignment
Migrate critical emails to templates Medium High Template design
Instrument tag() calls at send sites Medium Medium Tag taxonomy
Enable campaigns.enabled and validate mail:campaign Medium Low Migration + tagged traffic
Set up webhook tracking for primary provider Medium High Provider API access
Implement pixel tracking fallback Low Medium URL routing
Configure suppression lists and retries Low Medium Business rules
Set up pruning and analytics Low Medium Monitoring tools

Operational Impact

Maintenance

  • Database Maintenance:
    • Regular pruning (php artisan mail:prune) to manage log growth. Configure retention policies per status (e.g., keep bounces for 1 year, opens for 6 months). Pruning directly shrinks the campaign reporting window — align retention with how far back marketing needs to report, or snapshot campaign aggregates before pruning runs.
    • Monitor database size and query performance. Indexes are provided by default, but large tables may need optimization; confirm the tags column is indexed and that mail:campaign plans use it.
  • Configuration Drift:
    • Centralize email provider credentials (e.g., LARAVEL_MAIL_SENDGRID_SIGNING_SECRET) in a secrets manager (e.g., Laravel Forge, Vault).
    • Use environment variables for all configurable options to avoid hardcoding, including laravel-mail.campaigns.enabled per environment.
  • Template Updates:
    • Versioning is automatic, but manual testing is required after template changes. Use the PreviewTemplateAction to validate before deployment. Include plain-text output in the preview checklist now that 1.4.0 fixes text-part handling.
    • Document template variables and examples for non-technical stakeholders.
  • Tag Hygiene (new): Tags are effectively a reporting contract. Treat additions/renames as a governed change: a renamed tag silently splits a campaign's history into two report lines. Maintain a registry of canonical tags and audit for orphans periodically.

Support

  • Debugging:
    • Logging: Use mail:stats to query sent/delivered emails. Check mail_logs table for failed sends.
    • Tracking: Verify webhook signatures and payloads in provider dashboards. Test pixel tracking with tools like Mailtrap or Litmus.
    • Suppression Lists: Audit mail_suppressions table for false positives (e.g., typo’d emails).
    • Campaign Reports: When numbers look wrong, check in this order: (1) is the mail actually tagged and is the tag spelled as expected; (2) was campaigns.enabled on at send time; (3) do webhook events exist for the window; (4) has pruning removed the relevant rows. Most "broken report" tickets are tag typos or disabled config at send time, not aggregation bugs.
  • Common Issues:
    • Webhook Failures: Implement retry logic for failed webhook deliveries (e.g., queue delayed jobs). Late-arriving webhooks will change campaign rates retroactively — set expectations that reports are not immutable.
    • Pixel Blocking: Educate users that some email clients block images by default. Provide fallback instructions (e.g., "Enable images to track opens"). Open rates should be presented as directional, not precise.
    • CSS Inlining: Test emails in Outlook/Gmail to ensure compatibility. Use the PreviewTemplateAction to debug rendering.
    • Text-Part Regressions: If any template sends malformed or empty text bodies, verify whether it was relying on the pre-1.4.0 text() behavior and adjust the template rather than the package.
  • Provider-Specific Quirks:
    • SendGrid: May require additional headers (e.g., X-SMTPAPI) for advanced features; its category field is a natural mirror of package tags, so keep the two namespaces consistent to avoid divergent reporting.
    • SES: Webhook deliveries are asynchronous; account for delays in campaign metrics, particularly for the first hours after a send.

Scaling

  • Send Volume: Log write amplification is the primary scaling constraint. Beyond roughly low-hundreds of thousands of sends/month, move logging to queued jobs and confirm the tags column doesn't widen the hot write path unacceptably.
  • Report Volume: mail:campaign cost scales with rows-per-tag. Schedule reports off-peak, run against read replicas, or materialize daily snapshots into a summary table as stakeholder demand grows.
  • Concurrency: Link-rewrite/click endpoints and webhook receivers are public HTTP surfaces; ensure they are rate-limited and, ideally, isolated from primary application workers.
  • Ramp-up: Expect roughly one sprint for a Laravel team to reach steady state on logging + templates + webhooks, plus a few days to formalize tag conventions and validate campaign reports against provider dashboards. The 1.4.0 upgrade itself is a small fraction of that — the cost is organizational (tag taxonomy and report ownership), not technical.

Failure Modes

  • Silent Report Gaps: If campaigns.enabled is off in one environment or a send path bypasses tag(), those sends simply never appear in reports. There is no error — only missing rows. Mitigate with a periodic check that outbound tagged volume matches provider send volume.
  • Migration on Large Table: Column addition plus index build on a hot mail_logs table can cause write stalls. Failure mode is elevated send latency or timeouts during deploy, not data loss.
  • Tag Collision / Drift: Renamed or shared tags produce blended or split campaign metrics that look plausible and go unnoticed.
  • Metric Inversion from Late Signals: Bounces and complaints arriving days later change click-to-open and delivery rates after the fact; stakeholders who cached an early number will see "discrepancies."
  • Pruning vs. Reporting Race: Aggressive retention can delete a campaign's underlying rows before it is archived, permanently losing that report.
  • Pixel/Webhook Degradation: Provider webhook outage or blanket image blocking produces undercounted opens and clicks without surfacing an alert unless explicitly monitored.
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.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style