bradietilley / laravel-shortify
Shorten URLs from within Laravel
Requires
- laravel/framework: ^11.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^9.0
- pestphp/pest: ^2.0
- phpstan/phpstan: ^1.8
README
A simple yet flexible implementation of a URL Shortner in Laravel.
Introduction
Integrate your own cusom URL shortener into your Laravel App, and track who visits what!
Installation
composer require bradietilley/laravel-shortify
Config and migrations should be published:
artisan vendor:publish --tag="shortify-config"
artisan vendor:publish --tag="shortify-migrations"
Documentation
Shortening URLs → Basic usage
Statically:
You can statically call the BradieTilley\Shortify\Shortify
singleton to shorten urls:
$shortUrl = Shortify::make()->shorten($longUrl)->url; // https://app.com/s/Ws4BYCVLDDDh $shortUrl = Shortify::url($longUrl)->url; // https://app.com/s/5wHiKrKx5xV1
Dependency Injection:
The BradieTilley\Shortify\Shortify
singleton can be dependency injected:
public function handle(Shortify $shortify): void { $url = $shortify->shorten($this->invoice->getSignedUrl()); echo $url->url; // https://app.com/s/xpLurjDkBATw }
Shortening URLs → Shortening with an expiry
Sometimes your short URLs should be temporary. To achieve this, provide an expiry when shortening.
Viewing an expired URL will result in a BradieTilley\Shortify\Exceptions\ShortifyExpiredException
exception.
$shortUrl = Shortify::make()->shorten($longUrl, expiry: now()->addDay()); $shortUrl = Shortify::url($longUrl, expiry: now()->addDay());
URLs → ShortifyUrl
Model
The BradieTilley\Shortify\Models\ShortifyUrl
model is the map between an original URL and a short URL (unique by code).
Original URL
The original URL can be fetched via the original_url
property
$url = Shortify::url($longUrl); $url->original_url; // same as $longUrl
Shortened URL
The shortened URL can be fetched via the url
attribute
$url = Shortify::url($longUrl); $url->url; // https://app.com/s/xpLurjDkBATw
The ShortifyUrl
model overview:
- Fields:
id
→ auto incrementing IDcode
→ Unique URL slug/codeoriginal_url
→ The original URL (text length of 64 KB)visit_count
→ A running count of how many times this URL has been visited, for optimised querying (albeit, at the cost of continually updating this field)expired
→ Whether or not this URL has expiredexpires_at
→ Timestamp of when this URL expirescreated_at
→ Timestamp of when this URL was createdupdated_at
→ Timestamp of when this URL was updated (which will typically correspond to when it was last visited)- Attributes:
url
→ A computed shortened URL using the code and the current route configuration.
- Relations:
visits
→ Has manyShortifyVisit
models.
Visits ->ShortifyVisit
Model
The BradieTilley\Shortify\Models\ShortifyVisit
model represents a unique visit of a shortened url, tracking the user (if authenticated), IP address, and User Agent.
$url = ShortifyUrl::findByCode('my-short-url'); $url->visits; // Collection<ShortifyVisit>
The ShortifyVisit
model overview:
- Fields:
id
→ auto incrementing IDshortify_url_id
→ Foreign Key forShortifyUrl
user_id
→ Foreign Key for the visitedUser
ip
→ IP Address of visitoruser_agent
→ User Agent of visitorcreated_at
→ Timestamp of when the user visited the URL
- Relations:
user
→ TheUser
who visited the URLurl
→ TheShortifyUrl
visited
Customisation → Code Length
The code length defaults to 12, meaning the short URLs are always https://app.com/s/
followed by 12 alpha-numeric characters such as 50mqV1dfOrth
.
This can be configured via the shortify.routing.code_length
config variable.
Customisation → URL Path
The default is /s/{code}
but in some cases this won't be what you're after.
This can be configured via the shortify.routing.uri
config variable.
Customisation → URL Domain
The default is the default app domain but in some cases you may wish to use an alternative shorthand domain.
Note: You will need to register this other domain and configure the DNS as per usual -- this package does NOT provide that type of functionality.
This can be configured via the shortify.routing.domain
config variable.
Customisation → Redirect Controller
The default is a rudimentary redirect that is handled by this package, but sometimes you may want to customise how the redirect is handled -- perhaps you want it to be returned in a JSON response that matches how JSON redirects are performed in your app.
This can be configured via the shortify.routing.route
config variable.
Once configured, the original controller is inaccessible, and you now have full control over the handling of redirects.
Customisation → Models
As always with most Laravel packages, you can modify the models to use -- perhaps you want to track more information, add new helpers, etc. No worries.
This can be configured via the shortify.models.shortify_url
and shortify.models.shortify_visit
config variables which change the ShortifyUrl
and ShortifyVisit
models respectively.
Customisation → Turn off visitor tracking
Maybe you don't want tracking, or don't need it. Whatever the reasons are, you can disable the tracking of visits setting the shortify.feature.track_visits
config variable to false
.
This will prevent the shortify_urls.visit_count
field from incrementing and will prevent the shortify_visits
table from being populated.
Customisation → Everything else
The BradieTilley\Shortify\Shortify
singleton can be replaced by another Shortify instance within your service provider. For example:
Extend Shortify:
namespace App\Support; class Shortify extends \BradieTilley\Shortify\Shortify { public function generateCode(ShortifyUrl $url): string { return Carbon::now()->format('Ymd').'-'.Str::random(6); } }
Then register it:
$this->app->bind(\BradieTilley\Shortify\Shortify::class, \App\Support\Shortify::class);
Then use it:
echo Shortify::url($longUrl)->url; // 20241026-TWrCmX