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

Nova Horizon Link Laravel Package

mad-web/nova-horizon-link

A Laravel Nova package that adds a convenient link to your Laravel Horizon dashboard directly within Nova, giving developers quick access to queue monitoring, failed jobs, and metrics without leaving the admin panel.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package in the same Laravel application that already runs both Nova and Horizon:

    composer require mad-web/nova-horizon-link
    

    The service provider is auto-discovered, so no manual registration is required in config/app.php on Laravel 5.5+.

  2. Confirm Horizon is actually installed and reachable. This package only draws a link — it does not ship Horizon. You should already have laravel/horizon installed, migrations run, and the /horizon route responding for the same environment Nova is served from.

  3. Where to look first:

    • vendor/mad-web/nova-horizon-link/src/ — the service provider and any Nova tool/menu-item class. This tells you how the link is registered (a Nova::menu entry vs. a Tool).
    • config/horizon.php — specifically the path key. The link target depends on this value.
    • app/Providers/HorizonServiceProvider.php — the gate() method that governs who can view Horizon at all.
    • config/nova.php — Nova's own path and middleware, in case you mount Nova under a prefix.
  4. First use case: after install, refresh Nova. You should see a new sidebar entry (typically labelled Horizon or similar) that jumps straight to the Horizon dashboard. The day-to-day win is being able to go from "I'm in the admin panel" to "show me failed jobs / queue throughput" without typing a URL or remembering the environment's path.

  5. If you don't see the link: clear config and route caches (php artisan config:clear route:clear) and re-check whether the package's provider is listed under bootstrap/providers.php (Laravel 11+) or discovered via vendor/composer/installed.json.

Implementation Patterns

Plain sidebar link (default). The intended workflow is zero-config: install, refresh, click. Treat it as an ergonomic convenience rather than infrastructure — it should degrade gracefully if removed.

Pair it with Horizon's authorization gate. The most valuable integration is ensuring the Nova link is only visible to people who can actually load Horizon. If the package doesn't already defer to Horizon::check() / the viewHorizon gate, wrap or extend the menu registration so the link is hidden for non-authorized users rather than showing a 403 on click:

// app/Providers/NovaServiceProvider.php or a custom tool
Nova::menu(function (Menu $menu) {
    if (Gate::allows('viewHorizon')) {
        $menu->link('Horizon', fn () => '/horizon');
    }
});

Environment-aware display. A common pattern is to only expose the link where Horizon is actually enabled. In local/dev without a queue worker running, Horizon is noise; in production it's the primary debugging surface. Gate on app()->environment() or on a config toggle so the same codebase behaves correctly across stacks.

Custom target path. If Horizon is mounted under a prefix (config('horizon.path') === 'admin/horizon') or Nova is served from a separate subdomain, the default /horizon link will be wrong. Resolve the URL from config instead of hardcoding:

fn () => url(config('horizon.path', 'horizon'))

Composing into a custom Nova tool. If you already ship an ops tool (a dashboard or a "System" tool), add the Horizon link as a menu item inside it instead of relying on the package's global sidebar entry, keeping all observability links in one place.

Incident workflow. The practical pattern is: Nova resource shows a failing job ID → click the Horizon link → land on the job detail → retry or delete. Documenting this two-click path for the team is more useful than the install itself.

Gotchas and Tips

  • Horizon not installed → dead link. The package doesn't guard against Horizon being absent. If you conditionally install Horizon per environment (e.g. not in local), ensure the menu entry is also conditional, otherwise you ship a 404 to developers.
  • horizon.path mismatch. The single most common cause of a broken link is a non-default Horizon path. Check config/horizon.php; the package may hardcode /horizon rather than resolving from config.
  • Authorization lives in Horizon, not Nova. Nova admins are not automatically Horizon viewers — that's a separate gate (viewHorizon). Don't assume a Nova login grants Horizon access; verify with a non-superadmin account.
  • Config cache. After changing Horizon's path or the package's config, run php artisan config:cache (or clear it). Menu items are registered at boot, so a stale cache will keep pointing at the old URL.
  • Subdirectory / subdomain deployments. If the app is served from https://example.com/admin/ and Nova is at /admin/nova, a root-relative /horizon link breaks. Prefer generating the link with url() / route() over a string literal.
  • Middleware and session sharing. Horizon and Nova must sit behind compatible middleware (same domain, same session cookie) for the click-through to land authenticated. If Nova is on a different subdomain than Horizon, expect a login prompt.
  • Version pinning. The package is a thin wrapper with essentially one job; pin it in composer.json and be prepared to replace it with a five-line Nova::menu entry if it goes unmaintained or breaks against a Nova major upgrade. The functionality is trivial to reimplement.
  • Extension point. Because the surface area is tiny, the cleanest customisation is to not modify the vendor package at all — register your own menu item (as shown above) and drop the dependency if you need conditional visibility, custom labels, or icons.
  • Debugging: if the link silently fails to appear, check Nova's Menu service provider ordering and whether another package is calling Nova::menu in a way that shadows it; php artisan route:list | grep horizon confirms the target route actually exists in that environment.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource