Installation
composer require alpixel/redirect-bundle
Register the bundle in config/bundles.php (Symfony) or config/app.php (Laravel via Symfony bridge):
Alpixel\RedirectBundle\AlpixelRedirectBundle::class => ['all' => true],
Configuration Publish the default config:
php artisan vendor:publish --provider="Alpixel\RedirectBundle\AlpixelRedirectBundle" --tag="config"
Edit config/redirect.php to define:
storage_path: Where redirects are stored (default: storage/redirects.json).default_redirects: Predefined routes (e.g., ['/old-url' => '/new-url']).First Use Case Redirect an old URL to a new one:
use Alpixel\RedirectBundle\RedirectManager;
$redirectManager = app(RedirectManager::class);
$redirectManager->addRedirect('/old-page', '/new-page');
Test by visiting /old-page—it should now resolve to /new-page.
Dynamic Redirects Add redirects programmatically (e.g., after migration):
// In a controller or service
$redirectManager->addRedirect('/legacy/{id}', '/products/{id}', true); // Permanent (301)
Route-Based Redirects Integrate with Laravel’s routing system:
Route::get('/old-route', function () {
return redirect()->route('new.route');
})->middleware('redirect:old-route');
Use middleware to auto-redirect:
// app/Http/Middleware/RedirectMiddleware.php
public function handle($request, Closure $next) {
if ($request->is('old-route')) {
return redirect()->to('/new-route');
}
return $next($request);
}
Batch Processing Load/save redirects in bulk:
$redirects = $redirectManager->getAllRedirects();
$redirectManager->saveRedirects($updatedRedirects);
RedirectManager in API responses:
return response()->json(['redirect' => '/new-endpoint'], 302);
saved):
Product::saved(function ($product) {
$redirectManager->addRedirect(
"/old-product/{$product->old_slug}",
"/products/{$product->slug}"
);
});
Storage Permissions
Ensure storage/redirects.json is writable:
chmod -R 775 storage/
Debug: Check Laravel logs for file_put_contents errors.
Caching Headers
The bundle doesn’t auto-set Cache-Control headers. Manually add:
return redirect()->to('/new-url')->header('Cache-Control', 'no-store');
Route Conflicts
Avoid overlapping routes (e.g., /old and /old/*). Use regex or middleware to prioritize:
Route::get('/old/{id}', function ($id) {
return redirect()->route('new.route', ['id' => $id]);
})->where('id', '[0-9]+');
JSON Serialization
Custom objects in getAllRedirects() may fail. Ensure data is serializable or use arrays:
$redirectManager->addRedirect('/data', '/new', ['custom' => ['key' => 'value']]);
Log Redirects: Enable debug mode in config/redirect.php:
'debug' => env('APP_DEBUG', false),
Redirects will log to storage/logs/redirect.log.
Validate Storage Path:
if (!$redirectManager->storageExists()) {
$redirectManager->createStorageFile();
}
Custom Storage Override the storage adapter by binding a service:
$this->app->bind(RedirectStorageInterface::class, function () {
return new CustomStorageAdapter();
});
Redirect Events
Listen for redirect.added/redirect.removed events:
event(new RedirectAddedEvent('/old', '/new'));
Middleware Hooks
Extend the RedirectMiddleware to add logic:
public function handle($request, Closure $next) {
if ($request->is('admin/*')) {
return $next($request); // Skip redirects for admin
}
// ... rest of logic
}
How can I help you explore Laravel packages today?