Skip to content
PN Scripts

Plugins

Trailmark by PN Scripts

Rename a post or product and its old links keep working: one trait stores old slugs and answers them with a single 301 to the current URL, no route changes.

  • PHP 8.2+
  • Laravel 12
  • Laravel 13
  • Eloquent
  • Composer
  • Coming soon

Coming soon

Not published on its store yet, so there is no buy or download link. PN Scripts does not take payment for it here.

Model code with the HasSlugHistory trait next to real requests and their 301, 302, 200 and 404 responses

What it solves

The gap

Renaming a post or product in Laravel changes its URL, and every link in search results, newsletters and other sites starts returning 404 unless someone adds redirects by hand.

What it is

Trailmark records old slugs automatically and redirects them to the current URL through the route binding you already have.

How you use it

One trait and one migration replace a hand-kept redirect list for model URLs, with loops ruled out by design.

For Laravel developers running blogs, shops and content sites whose editors rename things and expect old links to keep working.

Who it is for

Use it when

  • Blogs where editors improve titles and slugs after publishing
  • Shops that rename products or categories without losing search traffic
  • Sites moving to cleaner slugs that must keep old links alive

Built for

  • Laravel developers and agencies building content and e-commerce sites
  • Teams that care about SEO and broken links after renames

What is inside

How it records

After every save the trait compares the slug column with its previous value. If it changed, the previous slug is stored in the slug_history table with the model type and key. If the new slug matches an old slug of the same model type, that history entry is removed, because a live slug always takes precedence.

How it redirects

The trait extends route model binding. When the normal lookup by slug finds nothing, Trailmark looks in the history and answers with a redirect to the same route with the current slug, keeping the query string and other parameters. Controllers that look models up themselves can call findBySlugOrRedirect().

Why it cannot loop

Old slugs point at the model, never at another slug, so there are no chains. Renaming back removes the slug from the history, a request that would redirect to its own URL gets the normal 404, soft-deleted models do not redirect, and only GET and HEAD requests are redirected.

Keeping the table small

Each old slug counts its hits and the time of the last one. The trailmark:prune command deletes entries recorded too long ago, entries nobody requested for a given number of days, entries beyond a per-model limit and entries whose model no longer exists. A dry run shows the counts first, and the command can run from the scheduler.

Specs

Availability
Coming soon
Vendor
PN Scripts
Type
Package
Platforms
Laravel, PHP
Pricing
One-time purchase Price to be announced.
License
Proprietary
Deployment
Download (ZIP with the Composer package, installed as a path repository)
Maturity
v1.0.0

Compatibility

Platform or runtime Supported versions Tested up to
Laravel 12.0 or newer 13.35.0
PHP 8.2 or newer 8.4.26

Stack

  • PHP 8.2+
  • Laravel 12
  • Laravel 13
  • Eloquent
  • Composer

Trailmark is coming soon

It is finished and tested. It is not on sale yet; this page will say where to get it when it is.

Coming soon

Not published on its store yet, so there is no buy or download link. PN Scripts does not take payment for it here.

Questions

A Laravel package with a model trait, a migration and an Artisan command that keep the old slugs of your models and redirect old URLs to the current ones.

PHP 8.2 or newer and Laravel 12 or 13, with a database supported by Laravel. It was tested on Laravel 13.35 and 12.69 with PHP 8.4 and SQLite.

An admin screen and redirects for URLs that are not tied to a model; for arbitrary path redirects you still need your own rules. Scoped child bindings are not redirected, and MySQL and PostgreSQL were not part of the test runs.

It was written against Laravel's route binding and Eloquent events and tested with real HTTP requests through the Laravel kernel. Created with AI assistance; recording, redirects, loop protection, soft-delete handling and the prune command were checked by PN Scripts with a PHPUnit and Orchestra Testbench suite (35 tests, SQLite in memory) on Laravel 13.35 and 12.69, and the release ZIP was installed into a fresh Laravel app and checked with real HTTP requests.

It is not on sale yet. When it is, this page will link to the store; PN Scripts does not take payment on this site.