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

Basekit Laravel Slugs Laravel Package

basekit-laravel/basekit-laravel-slugs

Generate clean, unique, SEO-friendly slugs for your Laravel models with ease. BaseKit Slugs handles transliteration, duplicate prevention, and custom separators, integrating seamlessly through Eloquent traits and model events. Lightweight, configurable, and quick to install.

View on GitHub
Deep Wiki
Context7

Getting Started

basekit-laravel-slugs is a brand-new package (v1.0.0, first public release), so the fastest path is to read the source before trusting the README — at 1.0.0 the docs are usually thinner than the code.

Minimal steps:

  1. composer require basekit-laravel/basekit-laravel-slugs:^1.0
  2. Publish any config/asset the service provider exposes: php artisan vendor:publish --provider="BaseKit\Slugs\SlugsServiceProvider"
  3. Confirm auto-discovery picked up the provider (php artisan about or php artisan package:discover), since a missing provider is the usual cause of "class not found" on a fresh 1.0.0 install.
  4. Apply the package's trait to the model you want slugs on, and make sure the slug column exists (add a migration if the package doesn't ship one you're meant to publish).

First use case to validate the package end-to-end: a Post model with a title that gets a unique slug on create, then resolved via route model binding (/posts/{post:slug}). If that works, the package is doing its job; everything else is configuration.

Where to look first, in order: src/ for the trait and the slug-generation class, config/ for the source field / separator / uniqueness strategy options, then tests/ — a 1.0.0 package's test suite is the most reliable documentation of intended behaviour.

Implementation Patterns

Trait-on-model, generation on create. The dominant pattern is a HasSlug-style trait plus a model property (or method) naming the attribute the slug is derived from. Set the source field explicitly rather than relying on a default, so a later column rename doesn't silently produce empty slugs.

Explicit slug source and per-model overrides. Most slug packages let you declare protected $slugSource = 'title'; on the model or override a generateSlug() method. Prefer the override when you need business logic in the slug (e.g. prefixing with a category, stripping marketing noise, or truncating at a word boundary).

Uniqueness scoping. If you have multi-tenant data, slugs almost always need to be unique per tenant, not globally. Look for a scope/where hook in the config and wire it to your tenant column early — retrofitting uniqueness scopes after you have data means a backfill plus a schema change.

Route model binding. Once the column exists, bind on it: Route::get('/posts/{post:slug}', ...). Remember this changes the failure mode — a renamed slug turns old URLs into 404s unless you add a redirect layer or a slug-history table.

Backfilling existing rows. Don't expect the trait to help with records created before install. Write a one-off artisan command or queued job that iterates existing models with chunkById() and generates missing slugs, then add a NOT NULL constraint. Run it in batches; generating slugs for a large table in a single request is a common way to hit memory limits.

Renaming behaviour is a product decision, not a technical one. Decide deliberately whether editing a title regenerates the slug. Stable slugs (generate once, never change) are safer for SEO and inbound links; regenerating requires slug history plus redirects. Most packages default to generate-once — verify and document your choice.

API/resource layer. Expose the slug alongside the ID rather than replacing it. Internal references keep using the primary key; only public URLs switch to slugs. This keeps the change small and reversible.

Gotchas and Tips

  • Soft deletes plus a unique index on slug. A soft-deleted row still occupies the slug, so the generator's uniqueness check may hand out a "-2" suffix while the original row is invisible to users. Decide whether uniqueness ignores trashed rows (which requires a partial index in Postgres, or an app-level check in MySQL) and make it explicit.
  • Column definition. Slugs generated from long titles will blow past a VARCHAR(255) or get silently truncated by MySQL's non-strict mode. Use a sensible length and truncate in the generator, keeping the -2, -3 suffix intact after truncation rather than appending past the limit.
  • Collision suffix races. Application-level "check then insert" uniqueness logic races under concurrency. If the package retries on a unique-constraint violation, you're fine; if it only pre-checks, wrap creation in a transaction with a retry, or lean on the DB constraint and catch the exception.
  • Transliteration and non-ASCII. Str::slug() punts on many scripts, producing empty strings for e.g. fully CJK titles. Add a fallback (random suffix, ID-based slug, or a custom transliterator) and test with your real content, not just English titles.
  • Empty or numeric-only source. A title of "2026" or "!!!" yields a degenerate or empty slug. Guard in the generator and fall back to a UUID fragment.
  • Config caching. After changing any package config, run php artisan config:clear in development and ensure the deploy pipeline runs config:cache — a stale cached config is a classic "my setting isn't applied" afternoon.
  • Extension points. Rather than forking, look for a bound interface (slug generator/strategy) in the container, a config-driven Generator::class key, or model-level override methods. Prefer registering your own implementation in a service provider — v1.0.0 packages change fast and hard forks make upgrades painful.
  • Pin the version and watch for 1.x minors. This is an initial release with no deprecation history, so treat the public API as not yet frozen. Use ^1.0 with a committed composer.lock, and read the changelog before each minor bump — slug-generation changes can silently rewrite URLs, so pair upgrades with a smoke test that asserts known slugs are unchanged.
  • Add your own test for slug stability. A single feature test asserting "creating a post yields slug x, updating the title does/doesn't change it" is cheap insurance against a minor release altering default behaviour.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
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