Mailbox for Laravel
Local in-app inbox that intercepts outgoing mail via a Symfony transport, stores it through pluggable drivers, and serves it via a self-contained Vue 3 dashboard. Zero coupling to the host app's frontend stack.
When to activate
- Writing tests that capture sent mail via
InteractsWithMailboxor theMailboxfacade - Configuring
config/mailbox.php(driver, path, gate, polling, retention) - Using or extending the
mailboxmail transport - Implementing custom
MessageStore/AttachmentStoredrivers (both halves of the pair) - Working with inline images via
Support\CidRewriter - Touching the dashboard Vue app under
resources/js/(note: Inertia is not used) - Running package commands:
mailbox:install,mailbox:clear,mailbox:dev-link,mailbox:upgrade
Quick reference
1. Test assertions → rules/testing.md
- Use
InteractsWithMailboxtrait — auto-clears between tests, exposes$this->mailbox() - Collection-level:
assertSent,assertNotSent,assertNothingSent,assertSentCount,assertSentTo,assertNotSentTo,sent,firstSent - Per-message fluent (off
firstSent()):assertFrom,assertHasTo,assertHasSubject,assertSeeInHtml,assertHasAttachment,assertHasHeader, etc.
2. Capture pipeline & custom drivers → rules/architecture.md
MailboxTransport→MessageNormalizer→CaptureService→MessageStoredriverCaptureServiceis the storage-driver-agnostic entrypoint — store, list, find, update, delete, purgeStoreManagerresolves drivers:sqlite(default — dedicated SQLite file),database(bring-your-own-connection — same Eloquent store),file(JSON on disk)MessageStorehas 10 methods,AttachmentStorehas 8 — both halves are paired, both must be implemented for a custom driver- Custom drivers register through
config('mailbox.store.resolvers')(singularstore), notManager::extend() Support\CidRewriterresolves inlinecid:references throughAttachmentStore, regardless of driver
3. HTTP & authorization → rules/http.md
- Routes mounted under
config('mailbox.path', 'mailbox')withweb+mailbox.authorizemiddleware - Authorization through the
viewMailboxgate — define your own gate before exposing in production MailboxControllerreturns Blade for browser requests, JSON when$request->wantsJson()is true
4. Dashboard frontend → rules/frontend.md
- Standalone Vue 3 app — Inertia is not used; talks to package's own JSON endpoints via axios
- Shared state in
resources/js/lib/mailboxStore.ts; usemailboxUrl()from the store to respect the configurable path prefix - Vite builds into
public/vendor/mailbox/(hot file atpublic/vendor/mailbox/mailbox.hot) - Reka UI primitives, TailwindCSS v4 — keep classes scoped/prefixed
5. Artisan commands → rules/commands.md
mailbox:install— run once aftercomposer require(publishes assets/config, runs migrations)mailbox:clear— clear stored mail;--outdatedhonors retentionmailbox:dev-link— symlink package assets when developing inside the package itselfmailbox:upgrade— v1 → v2 config/env rewriter
6. Conventions → rules/conventions.md
- Namespace
Redberry\MailboxForLaravel - No
env()outsideconfig/ - Constructor injection of interfaces; avoid facades inside core services
- Vue:
<script setup>, TypeScript for new files, scoped/prefixed Tailwind classes - File IO only through storage drivers
7. Things to avoid → rules/avoid.md
- Don't bypass the
MessageStorecontract - Don't add external services or self-hosted SMTP
- Don't render unsanitized HTML in the dashboard
- Don't import from the host app's frontend
- Don't leave
dd(),dump(),ray(),var_dump()in committed code
How to apply
- Identify the task surface (test, config, driver, dashboard, route) and read the matching rule file.
- Check sibling files in the package for the established pattern — match it.
- For exact API syntax of installed Laravel/Pest versions, verify with
search-docs.
Definition of done
- Tests added and passing (
composer test) - PHPStan passes (
composer analyse) - Pint passes (
composer format) - No new
env()outsideconfig/ - README/CHANGELOG updated for user-facing changes
- Conventional Commits format used (
feat:,fix:,chore:,test:,refactor:,docs:)
Source: RedberryProducts/mailbox-for-laravel — distributed by TomeVault.