builtforsmallbusiness/laravel-404-monitor

A 404 monitoring dashboard for Laravel with SEO and Googlebot tracking

Maintainers

Package info

github.com/Builtforsmallbusiness/laravel-404-monitor

Issues

Language:Blade

pkg:composer/builtforsmallbusiness/laravel-404-monitor

Statistics

Installs: 15

Dependents: 0

Suggesters: 0

Stars: 0

v1.0.4 2026-06-03 15:29 UTC

This package is auto-updated.

Last update: 2026-06-04 04:35:22 UTC


README

A lightweight 404 monitoring dashboard for Laravel applications. Track missing pages, identify broken internal links, monitor Googlebot crawl errors, and understand where your 404 traffic comes from — all without touching a log file.

Laravel PHP License

Features

  • Automatic tracking — no manual instrumentation, middleware registers itself
  • Source detection — classifies each 404 as bot, internal, external, or direct
  • Googlebot flag — instantly see which missing pages search engines are hitting (critical for SEO)
  • Hit counts — see which URLs are repeatedly failing, not just that they failed once
  • Last seen timestamps — know if a problem is ongoing or historical
  • Built-in dashboard — clean UI with search, source filtering, and clear actions
  • Zero dependencies — no frontend framework required, dashboard is self-contained

Installation

composer require builtforsmallbusiness/laravel-404-monitor

Publish and run the migration:

php artisan vendor:publish --tag=404monitor-migrations
php artisan migrate

Publish the config (optional):

php artisan vendor:publish --tag=404monitor-config

That's it. The middleware registers itself automatically via the service provider.

After installing, run this to confirm the dashboard URL:

php artisan 404monitor:info

Protecting the Dashboard

By default, the dashboard is denied to all users until you explicitly grant access. This is intentional — the package does not assume how your application manages admin access.

To grant access, add a gate definition to your App\Providers\AppServiceProvider:

use Illuminate\Support\Facades\Gate;

public function boot(): void
{
    Gate::define('view-404-monitor', function ($user) {
        return $user->is_admin; // your own logic here
    });
}

Common examples

Using a boolean column on your users table:

Gate::define('view-404-monitor', function ($user) {
    return $user->is_admin;
});

Using a role string:

Gate::define('view-404-monitor', function ($user) {
    return $user->role === 'admin';
});

Using Spatie Laravel Permission:

Gate::define('view-404-monitor', function ($user) {
    return $user->hasRole('admin');
});

Allowing specific emails (useful for small apps):

Gate::define('view-404-monitor', function ($user) {
    return in_array($user->email, [
        'you@yourdomain.com',
    ]);
});

Local environment only (during development):

Gate::define('view-404-monitor', function ($user) {
    return app()->environment('local');
});

Note: The gate receives the currently authenticated user. Make sure your dashboard route is also protected by the auth middleware (set by default in config/404monitor.php).

Dashboard

Access the dashboard at /_404-monitor (requires authentication by default).

To customise the route prefix or middleware, publish the config:

// config/404monitor.php

'route_prefix' => '_404-monitor',   // change the URL
'middleware'   => ['web', 'auth'],  // protect with your own middleware

Configuration

return [
    // Enable/disable the dashboard UI
    'dashboard_enabled' => true,

    // Dashboard URL prefix
    'route_prefix' => '_404-monitor',

    // Middleware applied to dashboard routes
    'middleware' => ['web', 'auth'],

    // URL patterns to skip (supports * wildcards)
    'ignored_urls' => [
        '/favicon.ico',
        '/apple-touch-icon*',
        '/robots.txt',
        '/.env',
        '/wp-*',
    ],

    // Partial user agent strings to ignore
    'ignored_user_agents' => [
        // 'SemrushBot',
        // 'AhrefsBot',
    ],

    // Days to retain records (null = keep forever)
    'retention_days' => 90,

    // Database table name
    'table_name' => 'failed_requests',
];

Source Types

Source Meaning
bot Automated crawler or spider (includes Googlebot, Bingbot, etc.)
internal Followed a link from within your own site — a broken internal link
external Followed a link from another website — a stale backlink
direct No referer — direct URL hit or unknown

Internal 404s are the most actionable — they indicate broken links in your own content that you can fix immediately.

Cleaning Up Old Records

Add the cleanup command to your scheduler to enforce the retention period:

// routes/console.php or app/Console/Kernel.php

Schedule::command('404monitor:clean')->daily();

Or run manually:

Artisan Commands

| Command | Description |
|---------|-------------|
| `php artisan 404monitor:info` | Display dashboard URL and setup info |
| `php artisan 404monitor:clean` | Remove records older than retention period |

Customising the Dashboard View

Publish the views to override them:

php artisan vendor:publish --tag=404monitor-views

Views will be copied to resources/views/vendor/404monitor/.

Using the Model Directly

use BuiltForSmallBusiness\Laravel404Monitor\Models\FailedRequest;

// Most-hit URLs
FailedRequest::orderByDesc('hit_count')->take(10)->get();

// Googlebot crawl errors
FailedRequest::googlebot()->get();

// Active in the last 24 hours
FailedRequest::recentlyActive(24)->get();

// Broken internal links
FailedRequest::where('source', 'internal')->get();

Why this exists

We built this for Built For Small Business after discovering that standard Laravel error logs give you no visibility into patterns of 404 errors. A single broken internal link generating 200 hits looks the same as 200 one-off bot probes — until you see the data in a dashboard.

The Googlebot tracking was the specific trigger: knowing which of your missing pages search engines are trying to crawl is directly actionable for SEO.

License

MIT — see LICENSE

Built by Built For Small Business · Report an issue