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

Filament Error Pages Laravel Package

cmsmaxinc/filament-error-pages

Filament Error Pages replaces Laravel’s default error screens with branded, Filament-styled pages for your admin panel. Customize 404, 403, 500 and other error views to match your app, with simple configuration and a consistent user experience.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package alongside a Filament panel (v3/v4 depending on the release line):

    composer require cmsmax/filament-error-pages
    
  2. Publish and run the migrations (the package stores error page content in the database, keyed by HTTP status code):

    php artisan vendor:publish --tag="filament-error-pages-migrations"
    php artisan migrate
    
  3. Register the plugin on the panel(s) that should manage error content:

    use CMSMax\FilamentErrorPages\FilamentErrorPagesPlugin;
    
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->plugin(FilamentErrorPagesPlugin::make());
    }
    
  4. Look first at the generated Error Pages resource in the panel — that is where each status code (404, 403, 500, 503, …) gets its title/body content. Create one record per status code you care about.

  5. First use case: replace the default Laravel 404 with a branded page. Create the 404 entry in the resource, hit a non-existent URL on the front end, and confirm the rendered page. From there, add 403/500/503 as needed.

Implementation Patterns

  • One record per status code, edited by content editors. The day-to-day workflow is non-technical: marketers/ops edit copy in the Filament resource, developers own the layout via the published Blade views. Keep the layout in version control, keep the copy in the database.
  • Register the plugin only on the panel that should own error content. In multi-panel apps, avoid exposing error page editing on a customer-facing panel; register it on the admin/staff panel and let the front end render whatever the package resolves.
  • Multi-tenant panels (new in v2.1). Error pages now resolve slug and subdomain tenants, so a acme.example.com 404 can show Acme's copy while beta.example.com shows Beta's. The pattern that works:
    • Enable tenancy on the panel as usual (->tenant(Team::class)).
    • Create per-tenant error page records via the resource while impersonating/in the context of each tenant.
    • Keep a tenant-agnostic fallback record so unresolved tenants (unknown subdomain, tenant deleted) still get a sane page rather than an exception.
  • Middleware ordering is the integration point. Error pages are rendered by the exception handler, which runs outside your panel's tenancy middleware in the normal request lifecycle. If you rely on tenant resolution, make sure the identifier your tenant resolver needs (subdomain or slug segment) is derivable from the request alone — don't depend on session, auth, or panel middleware having run.
  • Fallback-first rendering. Treat the database lookup as best-effort: try { resolve page } catch { use packaged view }. This keeps 500s renderable when the app is degraded.
  • Pair with Laravel's error view publishing (php artisan vendor:publish --tag=laravel-errors) if you need static fallbacks for the cases where the package cannot resolve a page (DB down, migrations not yet run, queue-worker context).
  • Localization. If you serve multiple locales, model the copy per locale in your own layer (separate records per locale, or a translatable trait on the model) rather than duplicating layouts.
  • Cache the resolved page. Error paths are hit by bots constantly; resolving a DB row on every 404 is wasteful. Cache per status + tenant key with a short TTL and clear it on save from the resource.

Gotchas and Tips

  • Database dependency on the 500 path. This is the classic failure mode for DB-backed error pages: your database is unreachable, so the error page lookup throws inside the exception handler and you get a blank white page or a secondary exception. Always keep a static Blade fallback and test it by pointing DB_HOST at a dead host.
  • 419 / 500 / 503 are special. A 500 may be caused by something that also breaks rendering (bad config cache, broken service provider). A 503 typically comes from php artisan down, where the app is intentionally minimal — verify your custom 503 actually renders during maintenance mode.
  • Tenant resolution on error pages (v2.1) is request-derived only. Slug and subdomain tenants work because they're readable from the URL. Session- or auth-derived tenancy will not resolve on an error page, because the exception may fire before authentication or before the session middleware group has run. Don't file bugs about it — design around it.
  • Unknown tenant = no tenant context. If a subdomain points at a tenant that doesn't exist, resolution fails. Decide whether that should be a 404 from your fallback record or an exception, and cover it with a test.
  • Ordering of middleware vs. the exception handler. If you write custom tenancy middleware, remember it only affects successful requests that reach the router. Errors thrown earlier (in global middleware, in a service provider) never see your tenant context. Keep a default record.
  • Config quirks. Check the published config for which status codes are managed and whether caching is toggled. If you change the managed status list after seeding, existing records may be orphaned — clean them up or leave them harmless.
  • Asset/version drift. After a major Filament upgrade, re-check the plugin's compatibility constraint. Filament v3 → v4 changed panel/resource APIs and plugins built for one often break on the other; pin the package version in composer.json until you've validated the panel.
  • Extension points. Prefer overriding the published Blade views and the resource's form schema over forking the package. If you need per-status logic (e.g. different layout for 503), do it in a small subclass or a view-level conditional rather than patching vendor code.
  • Testing tip. Add feature tests that hit /does-not-exist (expect 404 + your marker string), a forbidden route (403), and a deliberately throwing route (500). Run them in CI — error pages regress silently because nobody looks at them manually.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
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