URL Normalizer (force lowercase and trailing slash) WP Registry grade A. No security issues foundWP RegistryNo security issues foundOpen the reportA
WordPress plugin that enforces lowercase URLs and trailing slashes via 301 redirects.
Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/bvzk/wp-url-normalizer/archive/refs/heads/main.zipA lightweight WordPress plugin that enforces lowercase URLs and trailing slashes via 301 redirects. Zero dependencies, no settings page — just drop it in and it works.
What it does
- Lowercases all URL paths (
/About-Us/→/about-us/) - Enforces trailing slashes (
/about-us→/about-us/) - Collapses double slashes (
/about//us/→/about/us/) - 301-redirects anything that doesn't match canonical format
- Preserves query strings (
?utm_source=...passes through untouched)
What it skips
- Non-GET requests (POST, PUT, DELETE — untouched)
- WordPress admin (
/wp-admin/) - REST API (
/wp-json/) - AJAX, CRON, XMLRPC, CLI
- Static files (
.jpg,.css,.js,.png, etc.) /wp-content/and/wp-includes/
Installation
- Download
url-normalizer.php - Upload to
/wp-content/plugins/or/wp-content/mu-plugins/ - Activate in Plugins → Installed Plugins (not needed for mu-plugins)
No configuration needed.
Extending via filters
Disable path lowercasing (e.g. for OAuth callbacks or case-sensitive slugs):
add_filter('url_normalizer_lowercase_path', '__return_false');
Add custom skip prefixes:
add_filter('url_normalizer_skip_prefixes', function ($prefixes) {
$prefixes[] = '/my-custom-api/';
return $prefixes;
});
Why this exists
WordPress doesn't normalise URLs by default. The same page is accessible at:
/About-Us/
/about-us/
/about-us
Google treats these as separate URLs, splits your backlink value, and wastes crawl budget on duplicates. This plugin fixes that with a single 301 redirect at the init hook.
Requirements
- WordPress 5.9+
- PHP 8.0+
Compatibility
Tested on WordPress 6.9 with Yoast SEO and Cloudflare. The skip list covers common WP integration points — if you find a conflict, open an issue.
Changelog
1.6
- Fixed: scheme now taken from
home_url()— no longer hardcoded tohttps - Fixed: www no longer stripped from canonical host — prevents
wp_safe_redirectmismatch - Fixed:
is_ssl()used instead of$_SERVER['HTTPS']— works correctly behind reverse proxies - Added:
apply_filters('url_normalizer_skip_prefixes')— extensible skip list - Added:
apply_filters('url_normalizer_lowercase_path')— opt-out for path lowercasing - Added: host mismatch guard against Host header injection
- Added:
user_trailingslashit()— respects WordPress permalink settings
1.5
- Initial public release
Author
Eugene Bevziuk — bvzk.io
License
GPL-2.0-or-later — see https://www.gnu.org/licenses/gpl-2.0.html
Releases
2 releases.
These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.