phpsa/laravel-yourls-plugin
phpsa/laravel-yourls-plugin provides seamless YOURLS URL shortening integration for Laravel. Generate and manage short links through familiar Laravel APIs and configuration, making it easy to add branded, trackable short URLs to your projects.
Install the package and publish its config:
composer require phpsa/laravel-yourls-plugin
php artisan vendor:publish --provider="Phpsa\LaravelYourls\YourlsServiceProvider" --tag="config"
Set the two values you actually need in .env:
YOURLS_URL=https://sho.rt
YOURLS_SIGNATURE=your-yourls-signature-token
YOURLS_URL is the YOURLS installation base URL, not the API endpoint. The signature is the token from YOURLS’ “Secure passwordless API call” section, not your admin password.
The first useful use case is shortening a link inside a controller or service:
use Phpsa\LaravelYourls\Facades\Yourls;
$short = Yourls::shorten('https://example.com/a/long/campaign/link');
Before building around it, do a one-off dump() or dd() of the return value against your YOURLS instance. These wrappers are thin, and depending on the version the method may return the YOURLS JSON payload (with status, shorturl, url, title, keyword) or just the short URL string. Confirm that first, then decide whether you need a small adapter in your app.
If package discovery is disabled, register the service provider and facade alias manually in config/app.php. If the package does not support your Laravel version, check composer.json constraints and test on a branch before adopting it; the last release was December 2023.
Wrap it in your own service. Do not scatter Yourls::shorten() calls across controllers. Create an application service such as App\Services\ShortLinkService that owns URL shortening, stores the mapping, and normalises the package response:
class ShortLinkService
{
public function shorten(string $url, ?string $keyword = null): ShortLink
{
$response = Yourls::shorten($url, $keyword);
// Persist shorturl, keyword, target URL, and a local identifier.
// Normalise the package return shape here, not in controllers.
}
}
This gives you one place to add logging, retries, exception mapping, and tests.
Store the result. YOURLS already stores links, but your Laravel app usually needs its own record: the local model that owns the link, the campaign, the user, and the short URL. Store at minimum long_url, short_url, keyword, and created_by. Treat YOURLS as the redirect engine, not your source of truth.
Use custom keywords deliberately. A custom keyword is typically the second argument:
Yourls::shorten($url, 'spring-sale-2024');
Generate keywords from a slug plus a short random suffix, e.g. spring-sale-2024-a8f3, to avoid collisions. Check the YOURLS response before assuming success.
Batch and background work. For imports or bulk campaigns, dispatch jobs and throttle them. YOURLS is a PHP app backed by MySQL; hammering it from a queue worker with no delay will produce timeouts and duplicate-looking failures. Use Bus::batch() and a per-job delay or rate limiter.
Testing. If the package uses Laravel’s HTTP client, fake the YOURLS endpoint:
Http::fake([
'*/yourls-api.php*' => Http::response([
'status' => 'success',
'shorturl' => 'https://sho.rt/abc',
'url' => 'https://example.com/long',
'keyword' => 'abc',
]),
]);
If it uses Guzzle directly, bind a fake client or mock your own ShortLinkService instead. Either way, test the failure path: YOURLS returns HTTP 200 with status: fail for many errors.
Multiple environments or instances. Keep one config per environment. If you need multiple YOURLS installations, avoid changing global config at runtime; instantiate a small client per instance or create a dedicated service configured from a database row.
YOURLS_URL=https://sho.rt/ can produce https://sho.rt//yourls-api.php. Use https://sho.rt.{"status":"fail","code":"...","message":"..."} with a 200 response. Always check status before reading shorturl.format=json, set it in the config or pass it through. XML responses are painful to debug in Laravel.YOURLS_URL or YOURLS_SIGNATURE, run php artisan config:clear. In production, run php artisan config:cache as part of deploy.Http::retry() in your wrapper if the package exposes the client, or implement retry logic in your service. Do not retry aggressively on keyword collisions.Http is only a few lines.vendor/.How can I help you explore Laravel packages today?