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

Resource Navigation Link Laravel Package

digital-creative/resource-navigation-link

A Laravel Nova package that adds configurable navigation links to your resources, letting you jump quickly between related records or external destinations from a resource's index and detail views with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the field like any Nova package:

composer require digital-creative/resource-navigation-link

Laravel's package auto-discovery registers the service provider. If your app has discovery disabled, add DigitalCreative\ResourceNavigationLink\ResourceNavigationLinkServiceProvider to config/app.php. If the package ships compiled JS you may need php artisan vendor:publish --tag=nova-assets (or nova:publish) and a npm run dev/build in your Nova app — check README.md for the exact asset tag.

Where to look first:

  1. README.md — the supported method chain (the package is small; the field class in src/ is the source of truth).
  2. src/ResourceNavigationLink.php (or similar) — see which withMeta() keys the Vue component reads. That tells you exactly which public methods exist and what they do.
  3. resources/js/components/ — confirms how the URL and label are rendered (<a> vs. <Link>, target/rel handling).

First use case — turn a raw foreign key into a clickable link in the index/detail view:

use DigitalCreative\ResourceNavigationLink\ResourceNavigationLink;

public function fields(NovaRequest $request): array
{
    return [
        ResourceNavigationLink::make('Customer')
            ->resolveUsing(fn () => $this->customer)
            ->to(fn () => route('nova.customers.show', [
                'resource' => 'customers',
                'resourceId' => $this->customer_id,
            ])),
    ];
}

Even if the method names differ slightly in your installed version, the shape is the same: a Field subclass whose value or closure becomes the link target. The first thing to get working is a link from an index row to a related Nova resource detail page — that's the 80% use case.

Implementation Patterns

Link to a related Nova resource. For a belongsTo, resolve the URI at render time rather than hard-coding the resource name:

ResourceNavigationLink::make('Order')
    ->to(fn () => \Laravel\Nova\Nova::resourcePath($this->order->uriKey(), $this->order->getKey()))

or with a resource instance helper if the package exposes one (e.g. ->toResource(Order::class, 'order_id')). Prefer the resource class reference over a string so refactors/renames are caught by static analysis.

External navigation. Use it for outbound destinations: Stripe dashboard, CRM record, docs, S3 object presigned URL. Always set an absolute URL and make sure the component adds target="_blank" rel="noopener noreferrer". Generate signed URLs lazily in a closure so they aren't computed on list pages where the field is hidden.

Label vs. URL. Keep the displayed value meaningful (order number, customer name, status string). Use ->displayUsing() or a closure on make() to set the label, and use the package method to set the destination. Don't put HTML in the label unless the component explicitly renders raw HTML.

Conditional rendering. Combine with standard Nova field visibility: ->onlyOnIndex(), ->onlyOnDetail(), ->hideFromIndex(), ->canSee(fn () => $request->user()->can('view', $this->order)). This is the cleanest place to enforce that a link never points to a resource the user can't open.

In BelongsTo/MorphTo relationships. Use a single navigation link as a read-only presentation field next to (not instead of) the relationship field. The relationship field handles search/attach; the link field handles navigation from the index.

Subclass for repeated patterns. If you link to the same resource in many places, extract a small factory:

class OrderLink extends ResourceNavigationLink
{
    public function __construct(string $attribute = 'Order')
    {
        parent::__construct($attribute);
        $this->to(fn () => Nova::resourcePath('orders', $this->order_id));
    }
}

Compose with other fields. Use a companion text/searchable field for filtering and sorting; keep the link field presentation-only. In index tables, this gives you BelongsTo (searchable) + ResourceNavigationLink (clickable shortcut) side by side, or just the link if read-only.

Test at the three surfaces. A Nova field renders differently on index, detail, and form. A link field usually makes no sense on forms — assert onlyOnIndex/onlyOnDetail in your resource tests. Snapshot-test the JSON payload with $field->jsonSerialize() in a plain PHPUnit test.

Gotchas and Tips

  • It's not a column. A navigation link is a computed field; there's no migration and no $fillable entry. Don't accidentally add it to $casts or a query. If the value is derived, add ->onlyOnIndex()/->onlyOnDetail() so Nova doesn't try to render it in create/edit forms.
  • Closures run per row. ->to(fn () => ...) executes for every row on the index. If the closure hits the database, you've introduced an N+1 (or N+3). Eager-load the relationship in the resource's indexQuery or resolveUsing, and prefer $this->relation?->getKey() over a fresh Model::find() inside the closure.
  • Null-safety. Related models get deleted. Guard the closure with ?-> and fall back to a plain string field or ->hide(). A link to nova/resources/orders/ with an empty ID is a silent 404.
  • Internal vs. external URLs. Nova internal navigation is best done with a relative/resourcePath URL so the front-end router can intercept it; an absolute URL forces a full page load. For external targets, require https:// explicitly — otherwise the browser may resolve it relative to your app.
  • uriKey() at build time vs. runtime. Don't resolve Order::uriKey() in a property initializer where the resource may not be registered yet; resolve it inside the closure.
  • Policies still apply. The link is just an anchor. If a user can see the row but not the target resource, Nova returns 403. Pair canSee on the field with a Gate::check on the target policy if you want a graceful "no link" instead of a broken click.
  • Assets are the usual failure mode. After composer update, if the field renders blank or as JSON, run php artisan nova:publish (and rebuild) before debugging the field itself. Check the browser network tab for a missing resource-navigation-link.js.
  • Debugging the payload. dd(ResourceNavigationLink::make('X')->to(fn () => '/foo')->jsonSerialize()) in a controller test, or php artisan tinker, exposes exactly which meta keys the Vue component expects — faster than guessing method names from the README.
  • Sorting/filtering. These fields are not sortable and not filterable by default. Don't add ->sortable() hoping for it to work; add a separate database-backed field if sorting matters.
  • Extension point. The field's withMeta([...]) and jsonSerialize() overrides are the intended hooks. You can attach extra meta (e.g. a title tooltip or icon) without forking, if the component reads it — check the Vue file before assuming it does.
  • Pin the version. Released Jan 2025, low star count, no dependents. Pin to an exact minor in composer.json, and read src/ before upgrading a major Nova version — small Nova packages tend to break silently across Nova 4 → 5 because the Field base class and asset pipeline changed.
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.
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
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle