brilliant-packages/nova-relationships-link-list
A Laravel Nova package that renders relationships as a clean, clickable link list inside the admin panel, making it easy to browse related records at a glance. Useful for tightening Nova resource detail views without custom code.
This is a single-purpose Nova field: it renders a relationship as an inline, comma-separated list of links to the related Nova resources instead of Nova's default HasMany/BelongsToMany table. The value proposition is simple — compact detail views and fewer clicks — so evaluate it as a UI convenience, not infrastructure.
Minimal setup:
composer require brilliant-packages/nova-relationships-link-listcomposer.json (extra.laravel.providers). If not, register it in config/app.php.php artisan vendor:publish --provider="BrilliantPackages\NovaRelationshipsLinkList\..." or a tagged publish). Nova field components are JS assets; a missing publish step is the most common "field renders blank" cause.Where to look first:
->relationship('tags') vs. inferring from the field name) is the one thing you should not guess.src/ for the field class: the $component string tells you what the Vue component expects, and any public properties ($relationship, $displayField, etc.) tell you what is configurable.dist/ — if compiled assets are committed, installation is trivial; if not, you will need npm install && npm run prod inside the package.First use case: a Post detail page with a noisy HasMany "Tags" table. Replace it with:
use BrilliantPackages\NovaRelationshipsLinkList\RelationshipsLinkList;
public function fields(Request $request)
{
return [
// ...
RelationshipsLinkList::make('Tags')
->onlyOnDetail(),
];
}
The field name typically maps to the relationship method (Tags → tags()). Confirm that mapping before debugging anything else.
Detail-view compaction. The intended pattern is ->onlyOnDetail() alongside ->readonly(). This field is a display affordance; it does not give you form controls for attaching/detaching related models. Keep your BelongsToMany field on the form, and use this on the detail page.
One field per relationship. For resources with several many-to-many links (categories, tags, authors), stack multiple instances rather than trying to configure a composite field. Each instance resolves one relationship.
Eager loading is mandatory if you show it on index. A link list is cheap per model but the relationship is lazy-loaded by default. If you drop ->onlyOnDetail() and show it in the index, add the relationship to indexQuery:
public static function indexQuery(NovaRequest $request, $query)
{
return $query->with(['tags', 'categories']);
}
Without that, a 50-row index becomes 50+ extra queries per relationship.
Label resolution. These fields almost always derive link text from a conventional attribute (title, name, or Nova's $title). If your related model uses something else (label, slug), check whether the field exposes a display callback; if not, add a Nova title()/subtitle() to the related resource — that is the cleanest fix and benefits the rest of the admin.
Fallbacks. Nullable or empty relationships should render as an em dash or blank. Verify visually; a field that outputs , or an empty anchor is a common rough edge in small packages.
Combination with resolveUsing. If you need to filter which related models appear (e.g., only published tags), prefer a scoped relationship method on the model over fighting the field's resolution logic:
public function publishedTags()
{
return $this->tags()->where('published', true);
}
Then point the field at Published Tags. This keeps the logic testable outside Nova.
Extension point. Because the field is small, subclassing it or copying it into app/Nova/Fields is a legitimate pattern if you need different link formatting, badges, or a target="_blank" behaviour. At 5 stars and zero dependents, you are not inheriting a large API surface — you are inheriting one file and one Vue component.
composer.json, and budget an afternoon to verify it against your Nova major version (Nova 4 vs. Nova 5 component APIs differ). If it breaks on upgrade, forking is cheaper than waiting for a fix.relationships-link-list component means the JS was never published or built. Check dist/ in vendor/.->canSee().How can I help you explore Laravel packages today?