cleaniquecoders / shrinkr
Shrinkr is a Laravel package for shortening URLs, with custom slugs, analytics, branded domains, and seamless API integration.
Fund package maintenance!
Cleanique Coders
Requires
- php: ^8.2
- cleaniquecoders/traitify: ^1.0
- illuminate/contracts: ^10.0||^11.0
- jenssegers/agent: ^2.6
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^2.9
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^9.5
- pestphp/pest: ^2.34
- pestphp/pest-plugin-arch: ^2.7
- pestphp/pest-plugin-laravel: ^2.3
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^1.1
- phpstan/phpstan-phpunit: ^1.3
README
Shrinkr
Shrinkr is a Laravel package for shortening URLs, offering custom slugs, analytics, branded domains, and API integration.
Shrinkr makes it easy to convert long URLs into short, shareable links. With features like custom slugs, click analytics, branded domains, and seamless API support, Shrinkr empowers users to manage URLs effectively.
Features
- Shorten URLs with or without custom slugs.
- Analytics tracking: Track clicks, referrers, IP addresses, and devices.
- Branded domains: Use custom domains for shortened URLs.
- Configurable logging: Store logs in files or databases.
- API support: Programmatically shorten and resolve URLs.
-
Rate Limiting: To prevent abuse (e.g., spamming requests to shorten URLs or resolve them).Middleware: Added middleware configuration. Default isthrottle:60,1
. -
Protected URLs: Add password protection or other access restrictions to certain URLs, ensuring only authorized users can access the content.After further research, it's not relevant if the original URL is unprotected. Hence, this feature will be skip. -
QR Codes: Provide users with QR codes for easy sharing of URLs, especially on mobile devices.Use package such as Simple QrCode to generate the QR Code for the shortened URL. - Link Health Monitoring: Ensure that the original URLs are still reachable and valid & automatically disable or notify users if a link becomes broken or inactive.
- Event & Listeners: Improve system decoupling by using events to trigger actions asynchronously (e.g., logging clicks, sending notifications).
- Expiry: Allow expiry to be set - in minutes.
Installation
Install the package via Composer:
composer require cleaniquecoders/shrinkr
Publish the migration files and migrate:
php artisan vendor:publish --tag="shrinkr-migrations"
php artisan migrate
Publish the config file:
php artisan vendor:publish --tag="shrinkr-config"
The published configuration file (config/shrinkr.php
) will allow you to customize settings.
Configuration
You can configure logging options by modifying the config/shrinkr.php
file.
return [ 'logger' => \CleaniqueCoders\Shrinkr\Actions\Logger\LogToFile::class, // Default logger ];
To log to a database, change the logger to:
'logger' => \CleaniqueCoders\Shrinkr\Actions\Logger\LogToDatabase::class,
Usage
Here’s a basic usage example using the Shrinkr facade, actions, and events.
1. Shorten a URL
You can shorten a URL with or without a custom slug and expiry duration.
use CleaniqueCoders\Shrinkr\Facades\Shrinkr; // Shorten a URL with default random slug $shortUrl = Shrinkr::shorten('https://example.com/long-url', auth()->id()); echo $shortUrl; // Outputs: https://yourdomain.com/abc123 // Shorten a URL with a custom slug and expiry duration (e.g., 60 minutes) $shortUrlWithCustomSlug = Shrinkr::shorten('https://example.com/long-url', auth()->id(), [ 'custom_slug' => 'my-slug', 'expiry_duration' => 60, // Expires in 60 minutes ]); echo $shortUrlWithCustomSlug; // Outputs: https://yourdomain.com/my-slug
2. Retrieve the Original URL
Use the resolve()
method to retrieve the original URL from a shortened one.
$originalUrl = Shrinkr::resolve('abc123'); echo $originalUrl; // Outputs: https://example.com/long-url
When the URL is accessed, the UrlAccessed
event will be dispatched automatically to track the visit.
3. Update an Existing Short URL
You can update an existing short URL with a new custom slug or expiry duration.
use CleaniqueCoders\Shrinkr\Models\Url; use CleaniqueCoders\Shrinkr\Facades\Shrinkr; $url = Url::find(1); // Update the short URL with a new slug and expiry duration $updatedUrl = Shrinkr::update($url, [ 'custom_slug' => 'updated-slug', 'expiry_duration' => 120, // 2 hours from now ]); echo $updatedUrl->shortened_url; // Outputs: https://yourdomain.com/updated-slug
4. Event Handling
UrlAccessed Event
The UrlAccessed
event is dispatched whenever a shortened URL is accessed. You can listen for this event to log analytics or trigger notifications.
Example: Log URL Access in a Listener
namespace CleaniqueCoders\Shrinkr\Listeners; use CleaniqueCoders\Shrinkr\Events\UrlAccessed; use Illuminate\Support\Facades\Log; class LogUrlAccess { public function handle(UrlAccessed $event) { $url = $event->url; Log::info('URL accessed', [ 'url_id' => $url->id, 'shortened_url' => $url->shortened_url, 'accessed_at' => now(), ]); } }
UrlExpired Event
The UrlExpired
event is dispatched when a URL has expired, either through a scheduled check or upon access. You can listen to this event to notify the user or perform other actions.
Example: Notify on URL Expiry in a Listener
namespace CleaniqueCoders\Shrinkr\Listeners; use CleaniqueCoders\Shrinkr\Events\UrlExpired; use Illuminate\Support\Facades\Log; class NotifyUrlExpired { public function handle(UrlExpired $event) { $url = $event->url; Log::warning('URL expired', [ 'url_id' => $url->id, 'shortened_url' => $url->shortened_url, 'expired_at' => now(), ]); // Optionally, notify the user about the expired URL. } }
5. Automatically Expire URLs
If you’ve set an expiry duration, the URL will be marked as expired once that time has passed. You can also run the expiry command manually or schedule it.
Run the Expiry Command Manually:
php artisan shrinkr:check-expiry
Schedule the Expiry Command:
In your app/Console/Kernel.php
:
$schedule->command('shrinkr:check-expiry')->hourly();
6. Monitor URL Health
The Link Health Monitoring feature allows you to check if URLs are reachable and mark them as active or expired.
Check Health Action
Use the CheckUrlHealthAction
to manually check the health of a specific URL.
use CleaniqueCoders\Shrinkr\Actions\CheckUrlHealthAction; use CleaniqueCoders\Shrinkr\Models\Url; $url = Url::find(1); // Retrieve URL instance $action = new CheckUrlHealthAction(); $isHealthy = $action->execute($url); if ($isHealthy) { echo "URL is active."; } else { echo "URL is expired."; }
Check Health Command
Use the Artisan command to check the health of all URLs in bulk.
php artisan shrinkr:check-health
This command will:
- Check the status of all URLs.
- Mark expired URLs and dispatch the
UrlExpired
event. - Provide real-time output on the status of each URL.
Example output:
URL abc123 is now marked as active.
URL xyz456 is now marked as expired.
URL health check completed.
Schedule the Health Check Command
You can automatically run the health check at regular intervals using Laravel’s scheduler.
In your app/Console/Kernel.php
:
protected function schedule(Schedule $schedule) { $schedule->command('shrinkr:check-health')->hourly(); }
This will ensure that all URLs are continuously monitored and marked as expired when necessary.
7. Redirect Tracking
The redirect feature tracks detailed information such as:
- IP address of the visitor
- Browser and OS (via User-Agent parsing)
- Referrer (where the link was clicked)
- Headers and query parameters
- Optionally store logs in a database or log file
Example database log entry:
8. Routing
You can configure custom domain for the URL by configuring:
'domain' => 'bite.ly',
You may also change the middleware or add new one by configuring:
'middleware' => ['auth', 'verified', 'throttle:600,1']
Testing
Run the tests using:
composer test
Changelog
Refer to the CHANGELOG for the latest updates and changes.
Contributing
We welcome contributions! Please see CONTRIBUTING for guidelines.
Security Vulnerabilities
Report security vulnerabilities by reviewing our security policy.
Credits
License
Shrinkr is open-sourced software licensed under the MIT license.