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

Laravel Tags Laravel Package

spatie/laravel-tags

Add flexible tagging to Laravel Eloquent models with the HasTags trait. Create, attach, detach, and query tags with ease, with built-in support for tag types, translations, and sorting—ideal for organizing content across your app.

View on GitHub
Deep Wiki
Context7

Getting Started

Start by installing the package via Composer and publishing the migrations and config:

composer require spatie/laravel-tags
php artisan vendor:publish --provider="Spatie\Tags\TagsServiceProvider" --tag="tags-migrations"
php artisan migrate

Add the HasTags trait to any Eloquent model you want to tag:

use Spatie\Tags\HasTags;

class Article extends Model
{
    use HasTags;
}

Now you can immediately tag models using strings—tags are auto-created if they don’t exist:

$article = Article::create([
    'title' => 'Laravel Tips',
    'tags' => ['php', 'laravel'],
]);

Use the tags property or relationships to access tags, and scopes like withAnyTags() to query by tag.

Implementation Patterns

  • Tagging on creation/update: Pass a tags array in create() or fill(), or use syncTags() to replace all tags on an existing model.
  • Dynamic tag attachment: Use attachTag() / attachTags() for incremental tagging; detachTag() to remove individual tags.
  • Tag-based querying:
    • withAnyTags(['tag1', 'tag2']): models matching any tag
    • withAllTags([...]): models matching all tags
    • withoutTags([...]): exclude models with those tags
  • Tag types for separation: Use syncTagsWithType([...], 'type') or attachTag($tag, 'type') to keep context-specific tag collections (e.g., categories vs topics).
  • Internationalization:
    • Enable translatable tags using JSON name column. Use setTranslation('name', 'fr', 'mon tag') on Tag instances.
    • Access translations on models via $model->tagsTranslated() or $model->tagsTranslated('fr').
  • Custom Tag model:
    • Extend Spatie\Tags\Tag, override getLocale() to set a default locale for tags (e.g., admin-facing French but app locale English).
    • Register in config/tags.php via tag_model.

Gotchas and Tips

  • Slug generation: The slug is auto-generated using Str::slug() by default. Customize by setting 'slugger' => 'App\Str::slugCustom' in config or a custom closure.
  • Tag type scope leakage: The default scopes withAnyTags() and withAllTags() ignore tag types unless you explicitly pass a Tag instance created with a type. Use withAnyTagsOfType() for type-based filtering of models, not just tags.
  • Translations & querying: When filtering by translation, use JSON syntax: Tag::where('name->fr', 'mon tag'). Ensure your DB supports JSON querying (e.g., MySQL ≥5.7.8, PostgreSQL, SQLite ≥3.9).
  • Order column pitfalls: Tags are auto-ordered on creation (order_column). Remember to call save() after moveToStart(), swapOrder(), or setNewOrder(). Also note that order applies globally across tag types.
  • Performance: HasTags adds a morphMany relation on taggables, which is efficient but can be a bottleneck with huge tag sets. Use loadMissing('tags') in loops and consider pagination for large tag lists.
  • Migrations are optional but recommended: You must run the published migrations, but the taggables pivot table uses a polymorphic relation, so ensure foreign keys are allowed if your DB enforces them.
  • Testing tip: Use Tag::findOrCreate() in tests for idempotency, and wrap multi-language scenarios in App::setLocale() assertions.
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