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 Tags Improved Laravel Package

rhyslees/nova-tags-improved

An improved tags field for Laravel Nova that provides a smoother tagging experience with searchable options, inline tag creation, and configurable behavior for managing tag relationships in Nova resources.

View on GitHub
Deep Wiki
Context7

Getting Started

rhyslees/nova-tags-improved is a tags field for Laravel Nova — a fork that extends the common "tags input" pattern (type-to-create, chip UI, optional grouping) inside Nova resources. With only 2 stars, no dependents, and a last release in February 2023, treat it as a vendor-inlined utility rather than infrastructure you trust blindly. Pin the version.

Install

composer require rhyslees/nova-tags-improved
php artisan vendor:publish --tag=nova-tags-improved-config   # if the tag exists

If no config tag exists, check vendor/rhyslees/nova-tags-improved/ for config/, resources/, and src/ — the fork's README on GitHub is the authoritative source; read it before assuming any API.

Register the field

use RhysLees\NovaTagsImproved\Tags;

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        Text::make('Title'),
        Tags::make('Tags'),
    ];
}

First use case: an Article model with a tags column (JSON/array cast) or a spatie/laravel-tags relationship. Open the resource's fields() method, drop the field in, and verify the storage strategy the package expects before migrating — see Gotchas.

Where to look first, in order:

  1. The GitHub README diff against the upstream it forked from (likely spatie/nova-tags-field). The "improved" changes are the only reason to pick this over upstream.
  2. composer.json — confirms Nova version constraint and whether it depends on spatie/laravel-tags.
  3. src/ field class — shows the resolve*/fill* methods, which dictate your column type.

Implementation Patterns

Pattern 1 — JSON column, no extra package. The simplest and safest for a low-activity fork:

// migration
$table->json('tags')->nullable();

// model
protected $casts = ['tags' => 'array'];
Tags::make('Tags')
    ->help('Comma separated, press Enter to add');

The field writes an array into the column; display via a badge component or Text::make('Tags', fn ($a) => implode(', ', $a->tags ?? [])).

Pattern 2 — spatie/laravel-tags relationship. If the fork inherits the Spatie field's API:

Tags::make('Tags')
    ->type('article')          // Spatie tag type
    ->withLinkToTagResource()  // navigation to Tag resource
    ->onlyOnForms();

Guard this pattern carefully — it only works if the fork kept the Spatie integration intact. Confirm by grepping the src/ for Spatie\Tags imports.

Pattern 3 — Grouped / scoped tags. Common "improvement" over upstream is a ->group() or ->type() modifier so tags for articles don't pollute products. Wire it into the same JSON pattern with a nested structure:

Tags::make('Tags')->group('article');
// stores ['article' => ['laravel', 'nova']]

Pattern 4 — Index/detail display. Tags fields are typically form-only. If you want chips in the index, resolve them explicitly:

Text::make('Tags', fn ($a) => collect($a->tags ?? [])->take(3)->implode(' · '))
    ->onlyOnIndex(),

Integration tips

  • Filter by tag: add a Nova filter that queries the JSON column (whereJsonContains('tags', $value)) or the Spatie pivot, not a LIKE on a serialized string.
  • Searchable: if the fork exposes ->searchable(), back it with the same whereJsonContains logic in the model's searchable() scope; otherwise skip it.
  • API parity: keep the tag column and any tag endpoint consistent — if your frontend also edits tags, normalize strings (trim, lowercase) on both sides to avoid "Laravel" vs "laravel" duplicates.

Gotchas and Tips

  • Maintenance risk is the headline gotcha. Zero dependents, 2 stars, a single release in 2023. Do not let this package become load-bearing. If it breaks against Nova 5, you have no fallback except a fork or reading src/ yourself. Prefer it only when its "improvements" are concretely useful to you — otherwise reach for spatie/nova-tags-field directly.
  • Fork ancestry matters. Confirm which package it forked (check composer.json replace/require, and the README header). Copy the upstream's docs into your notes; the fork's README may be stale or incomplete.
  • Storage shape is undocumented, likely. Read fill() / resolve() on the field class. A JSON cast, a plain string, and a Spatie relation are three different migrations — picking the wrong one produces silent null on save or a PHP array to string exception on retrieve.
  • Nova version compatibility. composer.json will tell you the laravel/nova constraint. A 2023 release almost certainly predates Nova 5. If you're on Nova 5, test in a branch before merging — field component registration changed between Nova 4 and 5.
  • Type-to-create permissions. If the field allows creating tags, that bypasses Nova authorization on your Tag model. If you care about who can create tags, wrap the field in ->canSee(fn () => $user->can('create', Tag::class)) or lock the field to ->readonly() for non-admins.
  • N+1 on index views. Anything showing tag names in a table will trigger a query per row unless you eager-load: Resource::indexQuery(...)->with('tags'). This is invisible in tests with 3 rows and obvious at 300.
  • Config publishing. If vendor:publish finds nothing under the package's tag, check the service provider's boot() for a differently named tag. A silent no-op publish is a common foot-gun with low-maintenance forks.
  • Debugging tip: when tags silently disappear on save, dump $request->input('tags') in fill() first, then the model's $attributes['tags']. The gap between those two is almost always a $fillable/$casts mismatch, not a package bug.
  • Extension point: the field class is the extension point. If you need behavior it doesn't ship, subclass Tags in app/Nova/Fields/ and override resolve()/fill() rather than editing vendor/ — this also gives you a clean migration path off the package later.
  • License check. Forks sometimes change licenses or drop attribution. Verify before shipping to a client.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings