dillingham/nova-detail-link
Adds a configurable detail link to Laravel Nova resource index rows, letting you jump straight from a Resource's list view to its detail page or a custom URL. Simple to install, easy to customize, and handy for speeding up navigation in Nova admin panels.
Install
composer require dillingham/nova-detail-link
No publish step is required for a typical Nova field package — the service provider is auto-discovered and the compiled JS is served from vendor/. Run php artisan nova:publish only if you need to override the field's assets.
Read these first, in order
vendor/dillingham/nova-detail-link/README.md — it is short but defines the exact fluent API.vendor/dillingham/nova-detail-link/src/ — the field class shows you the real method names, the fill/serialization behaviour, and whether it wraps Text or extends Field directly.resources/js/components/ inside the package — confirms whether the link is built in PHP (passed as a URL meta key) or in the Vue component from resourceId/resourceName meta.Because this package was last released in April 2019, treat the source as the documentation. The README is minimal and the API surface is small.
First use case
You have a resource where a text column holds a human-readable reference to another record — an order line showing customer_name, a ticket showing assigned_to, a log row showing user_email — and you want that text clickable straight through to the related resource's detail page instead of making the user navigate manually.
Start by adding the field to one resource's fields() method, hit the index, and confirm the anchor renders and the URL matches what nova/resources/{resource}/{id} produces in your Nova version. Once that works, roll it out to the other resources.
Basic field
Add the field to fields() alongside your normal fields. It behaves like a text field for display purposes, but renders its value as an anchor.
use Dillingham\NovaDetailLink\DetailLink;
public function fields(Request $request)
{
return [
ID::make()->sortable(),
DetailLink::make('Name'),
// ...
];
}
Linking to a different resource's detail view
This is the reason to reach for the package. You configure the target resource and the attribute that holds its key, so the field can build the correct detail URL rather than assuming "current resource, current row".
DetailLink::make('Customer', 'customer_name')
->resource(\App\Nova\Customer::class)
->resourceId('customer_id');
Verify the exact method names against src/ — the package predates the fluent conventions Nova standardised in later versions, so it may use ->resource(...) plus an ID attribute, or a single ->detail($resource, $idAttribute) call.
Display value vs. link target
Keep the two concerns separate: let the field's value be whatever you want the user to read (an accessor, displayUsing, or a raw column), and let the link target come from a sibling column or a relationship. If you only have the related model available, resolve the ID explicitly:
DetailLink::make('Customer', fn () => $this->customer->name)
->resource(Customer::class)
->resourceId(fn () => $this->customer_id)
If the field doesn't accept closures, fall back to a computed attribute on the model, or resolveUsing/displayUsing where supported.
Scoping where it appears
Treat it like any other Nova field for placement: ->onlyOnIndex() when the detail view already has a proper relationship field, ->hideFromIndex() if the anchor is only useful on detail, ->onlyOnDetail(), and ->sortable() only if the underlying column is a real, sortable database column (see gotchas).
Pairing with relationship fields
A common, tidy pattern is: show the relationship field (belongsTo) for selection on forms, and show the DetailLink on the index/detail so people can jump across. You get the UX of a link without losing Nova's native relationship editing.
If the API doesn't fit, wrap it
Because this is a thin wrapper, the highest-leverage pattern is to subclass it or copy the field class into app/Nova/Fields/ and adjust. That gives you a stable internal API and insulates you from the package being unmaintained while still using its Vue component.
composer.json almost certainly pins an old laravel/nova range. You may need --with-dependencies, a version alias, or a local path repository. Don't fight it silently — check what constraint is actually blocking the install.authorizedToView on the target resource. A user who can see the source resource but not the target will click through to a 403. Gate the field yourself with ->canSee(...) or a policy check when the targets are sensitive.customer_id is null (soft-deleted, orphaned, optional FK), you'll either get a broken URL or an exception during serialization. Guard with ->displayUsing() returning a dash, or ->hide() when the ID is absent.->sortable() on a computed accessor or a joined column name will produce a SQL error; ->searchable() on an accessor won't search what the user sees.Nova::path(). If you serve Nova under a custom path or a subdirectory, confirm the link respects it rather than hardcoding /nova/. This is the first thing to check if links 404 in a non-default install.->withMeta([...]) and inspecting the serialized field in the JSON response (Network tab on the index page) tells you immediately whether the URL is built server-side and just being mis-rendered, or never built at all.<a href> to a detail route", which is a small custom field if the package stops working.How can I help you explore Laravel packages today?