Latest Version Craft CMS PHP Logging Library License
Intelligent redirect management and 404 handling for Craft CMS.
- Automatic 404 Handling - Catches all 404s and attempts to redirect
- Multiple Match Types:
- Exact Match - Case-insensitive exact URL matching
- RegEx Match - Full regular expression support
- Wildcard Match - Simple * wildcards
- Prefix Match - URL starts with pattern
- Statistics Tracking - Track all 404s (handled and unhandled)
- Auto-Redirect Creation - Automatically creates redirects when entry URIs change
- Smart Caching - Fast redirect lookups with tag-based cache invalidation
- CSV Export - Export statistics for analysis
- Multi-Site Support - Site-specific or global redirects
- Logging Integration - Uses logging-library for consistent logs
- Craft CMS 5.0 or later
- PHP 8.2 or later
- Logging Library 5.0 or greater (installed automatically as dependency)
Until published on Packagist, install directly from the repository:
cd /path/to/project
composer config repositories.craft-redirect-manager vcs https://github.com/LindemannRock/craft-redirect-manager
composer require lindemannrock/craft-redirect-manager:dev-main
./craft plugin/install redirect-managerOnce published on Packagist:
cd /path/to/project
composer require lindemannrock/craft-redirect-manager
./craft plugin/install redirect-manager- Go to the Plugin Store in your Craft control panel
- Search for "Redirect Manager"
- Click "Install"
Copy src/config.php to config/redirect-manager.php and customize:
<?php return [ // Auto create redirects when entry URIs change 'autoCreateRedirects' => true, // Statistics retention in days (0 = keep forever) 'statisticsRetention' => 30, // Maximum statistics records 'statisticsLimit' => 1000, // Preserve query strings in redirects 'preserveQueryString' => false, // Log level 'logLevel' => 'error', ];
<?php return [ '*' => [ 'autoCreateRedirects' => true, ], 'production' => [ 'logLevel' => 'error', 'statisticsRetention' => 90, ], 'dev' => [ 'logLevel' => 'debug', 'statisticsRetention' => 7, ], ];
Via Control Panel:
- Navigate to Redirect Manager → Redirects
- Click New redirect
- Fill in:
- Source URL:
/old-pageor/blog/*or regex pattern - Destination URL:
/new-pageor absolute URL - Match Type: exact, regex, wildcard, or prefix
- Status Code: 301 (permanent) or 302 (temporary)
- Source URL:
- Save
Programmatically:
use lindemannrock\redirectmanager\RedirectManager; RedirectManager::$plugin->redirects->createRedirect([ 'sourceUrl' => '/old-page', 'destinationUrl' => '/new-page', 'matchType' => 'exact', 'statusCode' => 301, 'enabled' => true, 'priority' => 0, 'siteId' => null, // null = all sites ]);
Exact Match:
Source: /old-page
Matches: /old-page (case-insensitive)
Wildcard Match:
Source: /blog/*
Matches: /blog/post-1, /blog/category/news, etc.
Prefix Match:
Source: /old-
Matches: /old-page, /old-blog, /old-anything
RegEx Match:
Source: ^/blog/(\d+)/(.*)$
Destination: /article/1ドル/2ドル
Dashboard:
- Navigate to Redirect Manager → Statistics
- View handled vs unhandled 404s
- See most common 404s
- Create redirects from unhandled 404s with one click
Export CSV:
Redirect Manager → Statistics → Export CSV
When enabled (default), the plugin automatically creates redirects when:
- Entry slug changes:
/old-slug→/new-slug - Entry moves in structure:
/parent/child→/new-parent/child
Disable in settings: Redirect Manager → Settings → Auto Create Redirects
# Create a test redirect via CP: # Source: /test-redirect # Destination: / # Match Type: exact # Status Code: 301 # Test it: curl -I http://your-site.test/test-redirect # Should return: HTTP/1.1 301 Moved Permanently # Location: http://your-site.test/
# Visit a non-existent page: curl -I http://your-site.test/page-that-does-not-exist # Check statistics: # CP → Redirect Manager → Statistics # Should show the 404 with "Handled: No"
- Create a test entry with slug
test-entry - Note the URL (e.g.,
/test-entry) - Change the slug to
renamed-entry - Save the entry
- Check Redirect Manager → Redirects
- Should see auto-created redirect:
/test-entry→/renamed-entry
# Create redirect: # Source: /old-blog/* # Destination: /blog/ # Match Type: wildcard curl -I http://your-site.test/old-blog/any-post # Should redirect to /blog/
# Run cleanup job manually: php craft queue/run # Or test the service directly: php craft console/controller/eval \ "echo lindemannrock\redirectmanager\RedirectManager::\$plugin->statistics->cleanupOldStatistics();"
- View redirects - View redirect list
- Create redirects - Create new redirects
- Edit redirects - Modify existing redirects
- Delete redirects - Remove redirects
- View statistics - Access 404 statistics
- View logs - Access plugin logs
- Manage settings - Change plugin settings
-
Check plugin is installed:
php craft plugin/list
-
Check database tables exist:
php craft migrate/all --plugin=redirect-manager
-
Check logs:
CP → Redirect Manager → Logs -
Enable debug logging:
// config/redirect-manager.php return [ 'logLevel' => 'debug', ];
-
Clear caches:
php craft clear-caches/all
- Check Settings → Statistics → Record Remote IP is enabled
- Check statistics limit hasn't been reached
- Check database:
SELECT * FROM redirectmanager_statistics
- Check Settings → General → Auto Create Redirects is enabled
- Check entry has a URI (not disabled, not in a disabled section)
- Check logs for any errors
Listen to redirect events in your own plugins:
use lindemannrock\redirectmanager\services\RedirectsService; use lindemannrock\redirectmanager\events\RedirectEvent; use yii\base\Event; Event::on( RedirectsService::class, RedirectsService::EVENT_BEFORE_SAVE_REDIRECT, function(RedirectEvent $event) { // Modify redirect before saving $event->redirect['statusCode'] = 302; // Or prevent saving // $event->isValid = false; } );
Available events:
EVENT_BEFORE_SAVE_REDIRECTEVENT_AFTER_SAVE_REDIRECTEVENT_BEFORE_DELETE_REDIRECTEVENT_AFTER_DELETE_REDIRECT
use lindemannrock\redirectmanager\RedirectManager; // Redirects $plugin = RedirectManager::$plugin; $plugin->redirects->createRedirect([...]); $plugin->redirects->updateRedirect($id, [...]); $plugin->redirects->deleteRedirect($id); $plugin->redirects->findRedirect($fullUrl, $pathOnly); // Statistics $plugin->statistics->record404($url, $handled); $plugin->statistics->getAllStatistics($siteId, $limit); $plugin->statistics->getChartData($siteId, $days); $plugin->statistics->exportToCsv($siteId); // Matching $plugin->matching->matches($matchType, $pattern, $url);
- Documentation: https://github.com/LindemannRock/craft-redirect-manager
- Issues: https://github.com/LindemannRock/craft-redirect-manager/issues
- Email: support@lindemannrock.com
This plugin is licensed under the MIT License. See LICENSE for details.
Developed by LindemannRock