Installation:
composer require a21ns1g4ts/filament-short-url
php artisan vendor:publish --provider="AshAllenDesign\ShortURL\Providers\ShortURLProvider"
php artisan migrate
short_urls table exists in your database.Register Plugin: Add to your Filament panel provider:
Filament::registerPanel(
Panel::make()
->plugins([
\A21ns1g4ts\FilamentShortUrl\FilamentShortUrlPlugin::make(),
]),
);
First Use Case:
/admin/resources/short-urls).https://example.com/long-path) and a slug (e.g., my-short-slug).yourdomain.com/my-short-slug.Generating Short URLs:
ShortUrl model directly:
use AshAllenDesign\ShortURL\Models\ShortUrl;
$shortUrl = ShortUrl::create([
'long_url' => 'https://example.com/long-path',
'slug' => 'custom-slug', // Optional; auto-generated if omitted
]);
$shortUrl->shortUrl; // e.g., "yourdomain.com/custom-slug"
Redirect Logic:
routes/web.php):
Route::get('/{slug}', [\AshAllenDesign\ShortURL\Http\Controllers\ShortUrlController::class, 'redirect'])
->where('slug', '[\w\-]+');
Bulk Operations:
Customizing Slugs:
ShortUrl::creating(function ($model) {
$model->slug = Str::slug($model->long_url, '-');
});
Integration with Filament Forms:
use A21ns1g4ts\FilamentShortUrl\Forms\Components\ShortUrl;
ShortUrl::make('short_url')
->required()
->rules(['required', 'url'])
Custom Short Domains:
ShortUrl model to support multiple domains:
$shortUrl = ShortUrl::create([
'long_url' => 'https://example.com',
'slug' => 'custom-slug',
'domain' => 'short.yourdomain.com', // Custom domain
]);
Route::get('{domain}/{slug}', [ShortUrlController::class, 'redirect'])
->where(['domain' => 'short\.yourdomain\.com', 'slug' => '[\w\-]+']);
Analytics Tracking:
redirect event to log clicks:
ShortUrl::observe(\AshAllenDesign\ShortURL\Observers\ShortUrlObserver::class);
clicks counter).API Endpoints:
Route::post('/api/short-urls', function (Request $request) {
return ShortUrl::create($request->validate([
'long_url' => 'required|url',
'slug' => 'nullable|string',
]));
});
Filament Widgets:
use A21ns1g4ts\FilamentShortUrl\Widgets\ShortUrlStats;
ShortUrlStats::class,
Slug Conflicts:
-1). To customize:
ShortUrl::creating(function ($model) {
$model->slug = $model->slug . '-' . Str::random(4);
});
Route Caching:
php artisan route:clear
Database Indexes:
slug column has a unique index (handled by the migration, but verify if extending the model).HTTPS Redirects:
Route::get('/{slug}', [ShortUrlController::class, 'redirect'])
->where('slug', '[\w\-]+')
->middleware('web');
Filament Permissions:
ShortUrl::resource()->visibleTo(fn (User $user) => $user->can('manage-short-urls'));
Missing Redirects:
php artisan route:list | grep short-url
slug column in the database matches the URL pattern.Auto-Generated Slugs:
ShortUrl::creating(function ($model) {
$model->slug = Str::of($model->long_url)->afterLast('/')->slug('-');
});
Performance:
long_url if querying by it frequently:
Schema::table('short_urls', function (Blueprint $table) {
$table->index('long_url');
});
Testing:
$this->actingAs($user)
->get('/admin/resources/short-urls')
->assertStatus(200);
Custom Storage:
ShortUrl model to store additional metadata (e.g., expires_at, tags):
Schema::table('short_urls', function (Blueprint $table) {
$table->timestamp('expires_at')->nullable();
$table->string('tags')->nullable();
});
Webhook Events:
ShortUrl::created(function ($shortUrl) {
event(new ShortUrlCreated($shortUrl));
});
Custom Validation:
ShortUrl model:
protected static function booted()
{
static::validate(function (NewShortUrl $validation) {
$validation->rule(function ($attribute, $value, $fail) {
if (str_contains($value, 'blocked-domain.com')) {
$fail('Domain not allowed.');
}
});
});
}
Localization:
'labels' => [
'title' => __('Short URL'),
'slug' => __('Custom Slug'),
],
Rate Limiting:
Route::get('/{slug}', [ShortUrlController::class, 'redirect'])
->middleware(['throttle:100,1']);
How can I help you explore Laravel packages today?