Skip to main content

Sharing and QR codes

A QR code on a poster cannot be reprinted, and a link in a newsletter cannot be edited after it is sent. Both need a target that is stable at print time and still correct a year later.

Route::get('/go/{token}', Polyslug\Http\Controllers\ShortLinkController::class);

$token = $product->shortLink(); // stable; /go/{token} 301s to the current canonical URL

shortLink() returns the same token for the same model and locale every time, so it is safe to print. The redirect is resolved at request time against the model's current canonical URL, so every rename in between is absorbed.

Bind a PolyslugUrlResolver once — the one class you write yourself, so the controller knows how to build the target. Without it every short link is a 404, which is the single most common reason a /go route appears not to work.

Making it short enough to print

A QR code's size grows with what it encodes, and a link people retype off a poster grows a typo rate with every character. Both are settings:

// config/polyslug.php
'short_links' => [
'scheme' => 'sequential', // 0, 1, … z, then 00 — the shortest link there is
'length' => 4, // or keep 'random' and shorten it
],

length is a floor, not a fixed width: once a width is used up the next link is one character longer rather than failing to be issued, so a short setting cannot leave you unable to print. php artisan polyslug:doctor reports how full the width is, which is the number to watch before a print run rather than after.

A counted scheme gives the shortest link possible and makes it predictable: k3f9 is followed by k3f8 and k3fa, so anyone can walk the set. On a public catalog that costs nothing. If the link is meant to be hard to find, keep 'random' and buy the length back — the gate below is what protects the content either way, but a guessable link means somebody can enumerate what exists.

A custom alphabet helps a link that gets read out loud:

'alphabet' => 'abcdefghjkmnpqrstuvwxyz23456789', // no 0/o, no 1/l/i

What a visitor cannot do with it

Short links resolve through polyslugResolveQuery(), so /go is not a way around a tenant or draft gate. An unknown token, a deleted model and a gated row all return the same 404.

See also