Installation
Requirements
- PHP 8.4+
- Laravel 13+ — 13.17+ only for the optional
laravel/headintegration, which is that package's own floor - PostgreSQL 18+, MySQL 8.4+, or SQLite
The uniqueness guarantees are enforced natively on each engine — a functional partial unique index on PostgreSQL and SQLite, equivalent generated key columns on MySQL — and the full suite runs against all three. So Polyslug works on Laravel Cloud (serverless Postgres plus MySQL 8.4 LTS) with no extra configuration.
Install
composer require pushery/polyslug-for-laravel
The service provider registers itself through package discovery.
Migrate
Polyslug stores its slugs in a polyslug_slugs table whose migration is registered
automatically, so a plain migrate is enough:
php artisan migrate
The package ships its migrations in order, and migrate applies all of them:
| Migration | What it does |
|---|---|
create_polyslug_slugs_table | The three tables — polyslug_slugs (every slug a model has ever had), polyslug_tokens (the key-to-token store the RandomTokenEncoder uses) and polyslug_short_links (the /go tokens) — plus the unique indexes that carry the uniqueness guarantees. |
add_enforce_unique_to_polyslug_slugs | The enforce_unique column behind shared slugs. |
scope_polyslug_tokens_to_a_model_type | Gives each morph type its own token space, so Page#1 and Wishlist#1 no longer share a token. |
add_polyslug_slugs_resolution_index | The index every incoming URL uses. Without it, resolution was a full table scan. |
pin_polyslug_token_collation | MySQL only: pins the token columns to a byte-exact collation, so a mixed-case alphabet keeps its entropy. A no-op on PostgreSQL and SQLite, which already compare byte-exactly. |
The two optional tables stay empty and inert until you use the feature behind them. See the database reference.
To manage the migrations in your application instead of loading them from the package,
publish them and disable the automatic registration in a service provider's register():
use Polyslug\PolyslugServiceProvider;
PolyslugServiceProvider::ignoreMigrations();
Publishing the package files
Nothing has to be published to use Polyslug. Publish what you want to customize:
php artisan vendor:publish --tag=polyslug-config # config/polyslug.php
php artisan vendor:publish --tag=polyslug-migrations # the slug + token tables
php artisan vendor:publish --tag=polyslug # both at once
Polyslug ships no views and no translations — it routes and resolves, it renders nothing and emits no user-facing text — so there is nothing else to publish.
Every option in the published config/polyslug.php is documented inline; the same options
are listed in the configuration reference.
Verify the setup
php artisan polyslug:doctor
The command checks that the configured encoder is valid and that the uniqueness-guaranteeing indexes exist, and exits non-zero when they do not. See Diagnostics.
Next
- Quick start — a sluggable model and a self-healing route.
- Backfilling existing rows — if your tables predate Polyslug.