pa-tmprod/ignition
Ignition is a beautiful, customizable error page for Laravel and PHP applications. It turns exceptions into detailed, readable reports with stack traces, source code snippets, request context, and suggested solutions, helping developers diagnose and fix failures faster.
Ignition is the development error page that ships with Laravel 6–8 (via facade/ignition); this fork is expected to be a drop-in replacement. In a normal Laravel 6/7/8 app you already have it — confirm with composer show | grep ignition and that APP_DEBUG=true in .env. If it is missing:
composer require --dev pa-tmprod/ignition
php artisan vendor:publish --provider="Facade\Ignition\IgnitionServiceProvider" --tag="ignition-config"
Where to look first:
config/ignition.php — the only file you should normally touch. It controls editor, theme, enable_share_button, enable_runnable_solutions, solution_providers, and per-exception solutions overrides.vendor/pa-tmprod/ignition/src/ — the Solutions/ directory is the best way to learn the API; every built-in solution (missing migration, missing Mix manifest, missing Vite manifest, etc.) is a small, readable class.Facade\IgnitionContracts\ProvidesSolution on them.First use case: throw a real exception from a route or a Blade view with APP_DEBUG=true, then use the page as a debugging surface — expand stack frames, click "Open in editor" next to a frame, read the solution banner if one is offered, and copy the request/route context instead of dd()-ing through a controller. That flow is the core day-to-day value: it replaces console-driven debugging with in-page context.
Attach a solution to a domain exception. This is the highest-leverage pattern — turn recurring support requests into self-serve fixes:
use Facade\IgnitionContracts\ProvidesSolution;
use Facade\IgnitionContracts\Solution;
class MissingApiKeyException extends Exception implements ProvidesSolution
{
public function getSolution(): Solution
{
return new class implements Solution {
public function getSolutionTitle(): string { return 'API key not configured'; }
public function getSolutionDescription(): string { return 'Add STRIPE_KEY to .env and run config:clear.'; }
public function getDocumentationLinks(): array { return ['Stripe keys' => 'https://dashboard.stripe.com/apikeys']; }
};
}
}
For one-off cases, skip the exception class and register the solution in config/ignition.php under solutions, keyed by exception class:
'solutions' => [
\App\Exceptions\TenantNotProvisioned::class => [
\App\Solutions\ProvisionTenantSolution::class,
],
],
Add a runnable action. Solutions implement getSolutionAction() returning RunCommand, RunScript, or OpenUrl. RunCommand (e.g., migrate, cache:clear) is the safe path; wire it to a command you already trust. Runnable actions only appear when enable_runnable_solutions is true — keep that local-only.
Register project-wide solution providers. If your solutions are derived from a shared library, implement SolutionProvider and list it in solution_providers. Useful for packages that want to contribute fix-it hints without touching the app's config.
Tune the editor link. Set IGNITION_EDITOR (or editor in config) to phpstorm, vscode, vscode-remote, sublime, atom, textmate, macvim, emacs, nova, or idea. "Open in editor" is the feature developers miss most when it is unset.
Use the page as a shared artifact during pairing. With enable_share_button on, the "Share" button produces a link you can paste into a PR or ticket; keep it disabled in anything reachable by non-developers.
Production fallback is the default. Because the package is require-dev, composer install --no-dev and APP_DEBUG=false naturally fall back to Laravel's plain error page. Do not add it to require; instead, rely on logs/Flare for production insight.
APP_DEBUG=true is the real switch, not the package. Ignition renders rich context (env, request body, session, headers) whenever debug is on. The single most common leak is APP_DEBUG=true in staging or production — verify it in every environment's .env, and set APP_ENV/APP_DEBUG explicitly in the deploy pipeline rather than relying on the default.Facade\Ignition\... (and Facade\IgnitionContracts\...). A fork that renamed the package but kept the namespace will be auto-discovered fine; if the fork changed namespaces, update both your exception imports and the published config's solution_providers. Check composer why pa-tmprod/ignition to see which package pulled it in, and pin to a specific version — the upstream (facade/ignition) was superseded by spatie/laravel-ignition for Laravel 9+, and a fork can drift.Facade\IgnitionContracts\ProvidesSolution becomes Spatie\IgnitionContracts\ProvidesSolution; class names are otherwise identical. Composer will not warn you — you'll just get a "class not found" at error-page render time, which is a confusing place to debug.enable_runnable_solutions defaults to false for this reason. Never enable it on a host that is not your machine; RunScript will happily accept any string, so never build an action from request data.PATH. For vscode, the code CLI must be installed (Shell Command: Install 'code' command); for WSL/containers use vscode-remote. The link is generated regardless, so a dead link points at the editor config, not at Ignition..env. After editing config/ignition.php or IGNITION_* in .env, run php artisan config:clear (not just config:cache). A cached config from a previous deploy is the usual reason a changed editor or theme "doesn't work."--tag=ignition-config publishes nothing, fall back to --provider="Facade\Ignition\IgnitionServiceProvider".WithoutExceptionHandling-style narrow reproduction, not to disable Ignition.SolutionProvider over monkey-patching; there is no supported public API for overriding the renderer itself, so keep customizations to solutions and config to survive upgrades.spatie/laravel-ignition (Laravel 9+) if you upgrade the framework, and do not build production error-reporting behavior on top of it.How can I help you explore Laravel packages today?