sly/url-shortener-bundle
Sly URL Shortener Bundle provides URL shortening capabilities for PHP applications, letting you create and manage compact links through a bundle-oriented integration. A lightweight option for adding short URL generation to your project.
First, calibrate expectations: this is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no config/url_shortener.php. As a Laravel developer your first decision is whether to (a) run it inside a Symfony service, (b) lift the provider logic into your own Laravel service, or (c) skip it and call bit.ly directly with Http::withToken(). Given 26 stars, zero dependents, and a low opportunity score, treat it as a reference implementation more than a dependency.
If you still want to install and read it:
composer require sly/url-shortener-bundle
The bundle's job is narrow: take a URL (usually one you built from an Eloquent model), hand it to a provider (bit.ly, goo.gl, or an "internal" DB-backed provider), and persist the resulting short URL so you can look it up later without re-shortening.
Where to look first: the bundle's DependencyInjection/Configuration.php (this is the real spec for every config key and provider option), then the provider classes and the manager service that orchestrates them. Read the manager first — it tells you the exact call sequence: build request → pick provider → persist short URL → return it.
First use case: shorten a public URL for a Post (e.g. https://yourapp.com/posts/123 → https://bit.ly/abc123), store the short URL and its provider on the record, and show it in a share widget. That single path exercises config, provider selection, persistence, and retrieval — everything else is variation.
Manager-as-a-service. The bundle centers on a manager service that wraps provider selection and persistence. In Laravel, bind your own equivalent in a service provider and inject it — don't scatter Http:: calls through controllers:
class ShortenerService
{
public function __construct(private ShortUrlRepository $repo) {}
public function for(Model $model): string
{
return Cache::rememberForever("short:{$model->getMorphClass()}:{$model->id}", function () use ($model) {
return $this->repo->firstOrCreateFor($model)
?? $this->repo->create($model, $this->provider->shorten($model->publicUrl()));
});
}
}
Provider abstraction. The bundle's value is the provider interface. Copy that shape — shorten(string $url): string plus a name() — so you can swap bit.ly for your own internal provider without touching call sites. Keep provider choice in config, not in code.
Internal provider = your own redirect table. The "internal management" mode is just a short_urls table (hash, target_url, provider, model_type, model_id, timestamps) with a unique index on hash, plus a catch-all route:
Route::get('/s/{hash}', fn (string $hash) => redirect(
ShortUrl::where('hash', $hash)->value('target_url'), 302
));
This is the pattern most teams actually keep; the external API calls are the part that ages badly.
Polymorphic linking. The bundle predates Laravel conventions, so port its entity-association idea to morphMany/morphOne. One short URL per model, enforced by a unique index on (model_type, model_id, provider) rather than by application logic.
Prefer async for anything bulk. Shortening on save is fine for single records; for imports or backfills, dispatch a job per model and let rate limits be handled by the queue's retry/backoff rather than a sleep() in a loop.
Cache the result. Short URLs are immutable. Cache forever keyed by model, and invalidate only if the target URL changes.
goo.gl is dead. Google shut down the URL Shortener API in 2019. Any sample or default referencing it will fail; delete that provider rather than debugging 404s.composer require to be the end of the work.config/url_shortener.php by hand, reading Configuration.php — it's the authoritative list of keys, defaults, and which are required.https://api-ff.bit.ly/v4/shorten). Send Authorization: Bearer and a JSON body — form-encoded requests return confusing 4xx errors.SELECT-then-INSERT.app/Support/ and own them.How can I help you explore Laravel packages today?