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

Sluggable Laravel Package

x-laravel/sluggable

x-laravel/sluggable is a Laravel package that simplifies generating URL-friendly slugs for Eloquent models. It automatically creates clean, unique slugs from chosen source fields, helping you build readable routes and SEO-friendly URLs with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Require the package via Composer, then publish its config and migrations. Run migrations before using slugs so the history table and unique index exist.
  • Add Contracts\HasSlug to your model and use Concerns\Sluggable. Implement the interface method that returns the attribute or attributes the slug is built from.
  • Make sure the model’s slug column is present, indexed, and unique. The package relies on that unique index for duplicate numbering and race retries.
  • First use case: replace manual slug assignment in a creating/saving hook. Let the trait generate the slug, then use route model binding or whereSlug() / findBySlug() in controllers.
  • Review the package config first for connection, history table, history model, pruning frequency/age/chunk size, and language/message settings.

Implementation Patterns

  • Basic model setup: implement HasSlug, use Sluggable, and return a single source attribute for normal slugs or an array for composite slugs.
  • Stable vs. regenerated slugs: leave regeneration disabled when URLs must remain stable after publication. Enable it per model only when the source title/name is expected to change and old URLs should follow.
  • Route binding and lookups: use whereSlug() and findBySlug() instead of raw where('slug', ...) so historical slugs resolve during the retention period. Route model binding should also resolve old slugs.
  • Uniqueness in scoped models: uniqueness is checked across global scopes, so multi-tenant or soft-deleted models should apply the same scopes during validation and saving. Keep validation and persistence scopes aligned.
  • Race-prone creates: rely on the package’s savepoint retry rather than writing your own unique-constraint retry around slug creation. Keep creations idempotent where possible.
  • Events: use Events\SlugChanged after commit for cache invalidation, redirect creation, search indexing, or audit logs. Use the slugChanging / slugChanged model events for model-local behavior.
  • Validation: use Rules\Slug for format checks and Rules\UniqueSlug when the slug must also avoid reserved history slugs. The slug string alias is convenient but watch for collisions with existing imports.
  • History and pruning: let model:prune remove old history rows. Tune retention age carefully: expired history rows stop resolving and stop reserving the slug.
  • Per-model tuning: keep package defaults global, then override language, regeneration, and uniqueness behavior on models that need different slug rules.
  • Localization: Turkish and English messages are included. Set the application locale appropriately if you rely on package validation messages.

Gotchas and Tips

  • Historical slugs remain reserved for a configurable period. If users expect a slug to be immediately reusable after rename, shorten retention consciously and accept that old URLs may stop resolving.
  • UniqueSlug considers reserved slugs, so it can reject a slug that is not currently attached to a record. Surface that clearly in forms, or users will see “taken” for an apparently free slug.
  • Savepoint retry depends on the database connection supporting savepoints. Verify behavior on your production driver, especially if you use multiple connections or long-running transactions.
  • SlugChanged is dispatched after commit. Do not assume listeners run inside the same transaction, and avoid duplicating the same side effect in both model observers and the event listener.
  • Global scopes define uniqueness boundaries. Queries using withoutGlobalScopes() can create collisions that validation did not see; keep bypass usage out of slug creation paths.
  • Route binding through history is convenient but can produce multiple URLs for one record. Add canonical redirects if SEO matters.
  • The package schedules pruning itself, but the Laravel scheduler must actually run. Check schedule:run / cron and confirm the configured frequency, age, and chunk size match your table size.
  • If you configure a separate history connection, keep migrations, the history model, and transactions aligned. Cross-connection transactional behavior is a common source of confusing history rows.
  • The slug validation alias is handy but can conflict with existing rule aliases or imports; use the fully qualified rule class in shared validation code.
  • For extension, prefer the documented per-model tunables and configurable history model/connection over overriding slug generation internals. Custom generation logic can break the package’s duplicate numbering, history, and retry assumptions.
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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle