Download the PHP package basekit-laravel/basekit-laravel-slugs without Composer
On this page you can find all versions of the php package basekit-laravel/basekit-laravel-slugs. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download basekit-laravel/basekit-laravel-slugs
More information about basekit-laravel/basekit-laravel-slugs
Files in basekit-laravel/basekit-laravel-slugs
Package basekit-laravel-slugs
Short Description Slugs and localized slugs for Basekit Laravel — deterministic slug generation, normalization and validation plus a reusable Eloquent trait that any model (Page, Post, Product, ...) can opt into.
License MIT
Homepage https://github.com/basekit-laravel/basekit-laravel-slugs
Informations about the package basekit-laravel-slugs
Basekit Laravel Slugs
Localized slugs for Eloquent models.
Store one slug per locale on any model using a shared polymorphic slugs table. Slugs can be set manually, generated from a value, or created automatically when a model is created.
Generated slugs are normalized, transliterated to ASCII by default, and automatically suffixed when a duplicate exists.
The package only manages slugs. Routing, URLs and SEO remain part of your application.
Requirements
- PHP 8.4 or 8.5
- Laravel 13
Installation
Install the package:
Publish the migration and run it:
This creates the shared slugs table.
The default configuration works without publishing a config file. To change it:
Usage
Add the HasSlugs trait to any Eloquent model:
Setting and reading slugs
Slugs are stored per locale:
When no locale is passed, the package uses the configured default locale, falling back to config('app.locale').
setSlug() stores the value exactly as provided. It does not normalize or modify it.
Generating a slug
Use setSlugFrom() when you want the package to generate the slug:
You can also specify a locale:
By default, generated slugs:
- use
-as the separator - transliterate accented characters to ASCII
- add a numeric suffix when the slug already exists
For example:
Duplicate slugs
Generated slugs are unique per model type and locale.
If the generated value already exists, a numeric suffix is added:
Different model types may use the same slug:
Different locales may also use the same value.
You can disable automatic disambiguation in the config:
A duplicate generated slug will then fail on the database unique constraint.
setSlug() never adds a suffix. It always attempts to store exactly the value you provide.
Finding models by slug
Use whereSlug() to query a model:
For multiple slugs, use whereSlugIn():
The list is resolved in a single query. An empty list matches nothing.
Automatic slug generation
The package can generate a slug automatically when a model is created.
Enable it in the config:
Now models using HasSlugs receive a slug from that attribute:
Automatic generation:
- runs only when the model is created
- does not replace an existing slug
- does not update the slug when the source attribute changes
- skips generation when the source attribute is empty
- only generates the default locale
- applies duplicate suffixes when needed
This keeps existing URLs stable when a model title changes.
Per-model source attribute
The configured source attribute is global, but individual models can override it:
A model can opt out of automatic generation entirely:
You can still call setSlugFrom() manually on that model.
Transactions when disambiguation is disabled
Automatic slug generation happens after the model has been inserted.
If disambiguation is disabled and the slug insert fails because of a duplicate, the model row has already been created.
Use a transaction when both writes should succeed or fail together:
Using the generator directly
The slug generator can also be used independently of a model:
Configuration
The default configuration is:
Default locale
When default_locale is null, the package uses:
You can set it explicitly:
Unicode slugs
By default, accented characters are transliterated:
To keep Unicode characters:
This allows slugs such as:
Separator
Change the generated slug separator with:
For example:
Deleting models
Slug rows are deleted when their model is deleted.
Models using SoftDeletes keep their slugs while they are soft deleted. A force delete removes the associated slug rows.
UUID and ULID primary keys
The published migration uses an unsigned big integer for sluggable_id, matching Laravel's default auto-incrementing primary key.
If your models use UUIDs or ULIDs, update the published migration before running it:
Then tell the model that string keys are supported by the slug storage:
Only change the migration to string keys when your sluggable models actually use UUIDs or ULIDs.
Morph maps
The package uses Eloquent's polymorphic type resolution, so existing morph maps are respected.
For example:
No additional package configuration is required.
Testing
The package includes a factory for slug rows:
Call forSluggable() once for each slug row you want to create.
How it works
All slugs are stored in one polymorphic slugs table.
Each row contains:
sluggable_typesluggable_idlocaleslug
The database enforces:
- one slug per model and locale
- one occurrence of a slug per model type and locale
This means two different model types can use the same slug, and the same slug can be used in different locales.
If your application requires slugs to be unique across all model types, adjust the indexes in the published migration.
Contributing
Bug reports and pull requests are welcome.
Before submitting a change, run:
Tests use in-memory SQLite by default.
To run the suite against another database, configure TEST_DB_CONNECTION as sqlite, mysql or pgsql together with the corresponding database connection environment variables.
Please report security issues privately. See SECURITY.md.
License
MIT. See LICENSE.md.
All versions of basekit-laravel-slugs with dependencies
illuminate/contracts Version ^13
illuminate/database Version ^13
illuminate/support Version ^13