Weave Code
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 Field Laravel Package

spatie/nova-tags-field

Nova field for tagging resources using spatie/laravel-tags. Add the HasTags trait to your Eloquent models and use the Tags field in Nova to create, assign, and manage tags. Requires MySQL 5.7.8+ and installs via Composer.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require spatie/nova-tags-field
    

    Then publish the migration for the underlying spatie/laravel-tags package:

    php artisan vendor:publish --provider="Spatie\Tags\TagsServiceProvider" --tag="migrations"
    php artisan migrate
    
  2. Register the Field Add the field to your Nova resource:

    use Spatie\NovaTagsField\TagsField;
    
    class Post extends Resource
    {
        public function fields(Request $request)
        {
            return [
                // ...
                TagsField::make('Tags'),
            ];
        }
    }
    
  3. First Use Case

    • Edit a resource in Nova and use the tag input (comma-separated or space-separated).
    • Tags are automatically saved to the tags pivot table (created by spatie/laravel-tags).

Implementation Patterns

Workflows

  1. Basic Tagging Use the default TagsField for simple tagging:

    TagsField::make('Tags')->onlyOnDetail(true); // Optional: Show only on detail view
    
  2. Customizing Display Override how tags are displayed in lists or details:

    TagsField::make('Tags')
        ->displayUsing(function ($tags, $resource) {
            return $tags->pluck('name')->implode(', ');
        });
    
  3. Validation & Rules Validate tags in your resource model:

    use Spatie\Tags\HasTags;
    
    class Post extends Model
    {
        use HasTags;
    
        protected $rules = [
            'tags' => 'required|min:1', // Example: Ensure at least 1 tag
        ];
    }
    
  4. Integration with Search Use the underlying spatie/laravel-tags package to search by tags:

    $posts = Post::withTags($request->input('tag'))->get();
    
  5. Bulk Actions Add a bulk action to filter resources by tags:

    public function availableForIndex(Request $request)
    {
        return $request->user()->can('view posts') ? Post::withTags($request->input('tag')) : Post::none();
    }
    
  6. Tag Suggestions Preload common tags for autocomplete:

    TagsField::make('Tags')
        ->suggestedTags(['laravel', 'nova', 'php']);
    

Gotchas and Tips

Pitfalls

  1. Migration Conflicts

    • Ensure the spatie/laravel-tags migration runs before your resource migrations to avoid table/column conflicts.
    • If using custom pivot tables, override the tagsTable() method in your model:
      class Post extends Model
      {
          use HasTags;
      
          public function tagsTable()
          {
              return 'post_tags'; // Custom pivot table
          }
      }
      
  2. Tag Syncing

    • Nova’s TagsField uses sync() by default. If you need attach()/detach(), override the field’s resolveAttribute:
      TagsField::make('Tags')
          ->resolveUsing(function ($resource) {
              return $resource->tags()->pluck('name');
          })
          ->storeUsing(function ($resource, $tags) {
              $resource->tags()->sync($tags);
          });
      
  3. Performance with Large Datasets

    • Avoid eager-loading tags on lists with many resources. Use withCount('tags') instead:
      $posts = Post::withCount('tags')->get();
      
  4. Case Sensitivity

    • Tags are case-sensitive by default. Normalize tags in your model:
      protected static function bootHasTags()
      {
          static::saving(function ($model) {
              $model->tags = collect($model->tags)->map(fn($tag) => strtolower($tag));
          });
      }
      
  5. Nova Tool Conflicts

    • If using other Nova tools (e.g., spatie/nova-search), ensure they don’t conflict with tag queries. Use scopes or custom queries to isolate logic.

Debugging Tips

  1. Check Pivot Table Verify tags are saved correctly:

    php artisan tinker
    >>> \App\Models\Post::first()->tags
    
  2. Log Field Resolution Debug field resolution by adding a temporary log:

    TagsField::make('Tags')
        ->resolveUsing(function ($resource) {
            \Log::debug('Resolving tags for post ID: ' . $resource->id);
            return $resource->tags()->pluck('name');
        });
    
  3. Clear Cached Views If tags don’t update in Nova, clear the view cache:

    php artisan view:clear
    

Extension Points

  1. Custom Tag Model Extend the default Tag model:

    class CustomTag extends \Spatie\Tags\Tag
    {
        public function scopeActive($query)
        {
            return $query->where('is_active', true);
        }
    }
    

    Then bind it in AppServiceProvider:

    public function boot()
    {
        \Spatie\Tags\Tag::swap(new \App\Models\CustomTag());
    }
    
  2. Custom Tag Field UI Override the Vue component for advanced UI (e.g., color-coded tags):

    Nova.require('@spatie/nova-tags-field', (resolve) => {
        return resolve.then(() => {
            Nova.booting((Vue, router, store) => {
                router.addRoutes({
                    name: 'custom-tags-field',
                    path: '/custom-tags-field',
                    component: require('./CustomTagsField.vue'),
                });
            });
        });
    });
    
  3. Tag Metadata Store additional metadata (e.g., tag color) in the pivot table:

    Schema::create('post_tags', function (Blueprint $table) {
        $table->id();
        $table->foreignId('post_id')->constrained()->cascadeOnDelete();
        $table->foreignId('tag_id')->constrained()->cascadeOnDelete();
        $table->string('color')->nullable(); // Custom field
        $table->timestamps();
    });
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport