When configuring Nginx for Magento, URL consistency becomes crucial for SEO and canonicalization. The missing trailing slash issue particularly affects:
- Magento category pages
- CMS page URLs
- Custom route endpoints
Standard Nginx rewrite approaches often break Magento's front controller pattern. The common mistake:
# This causes redirects to /index.php/
rewrite ^([^.]*[^/])$ $1/ permanent;
This configuration handles both static files and Magento's front controller:
server {
# ... existing configuration ...
# Handle trailing slashes for non-file requests
if ($request_uri ~* "^[^?]*?[^/?]+$") {
rewrite ^([^.]*[^/])$ $1/ permanent;
}
# Magento's existing front controller pattern
location / {
try_files $uri $uri/ @handler;
}
# ... rest of your Magento config ...
}
For URLs with query parameters:
if ($request_uri ~ "^[^?]*[^/]$") {
return 301 $uri/$is_args$args;
}
Verify with these curl commands:
curl -I http://example.com/contacts
# Should return 301 to /contacts/
curl -I http://example.com/category.html
# Should NOT redirect (file extension present)
The if() directive has some overhead. For high-traffic sites, consider:
- Using map directives instead
- Implementing at the load balancer level
- Handling via Magento's URL rewrite system
When running Magento on Nginx, you might encounter situations where URLs without trailing slashes create duplicate content issues or inconsistent behavior. For example:
http://example.com/contacts (missing slash) http://example.com/contacts/ (correct version)
Most generic Nginx solutions for adding trailing slashes don't work well with Magento because:
- Magento's front controller pattern (index.php) interferes with simple rewrite rules
- Static files and media URLs shouldn't get trailing slashes
- The solution must preserve query strings
Here's the proper way to implement 301 redirects for missing trailing slashes in Magento:
server { # ... other server config ... # Handle directory requests - add trailing slash if ($request_uri ~ ^/([^?]*[^/])$) { return 301 /$1/; } # Magento's standard rewrite rules location / { try_files $uri $uri/ @handler; } location @handler { rewrite / /index.php; } # ... rest of Magento config ... }
Static Files: The solution above won't add slashes to actual files (like .css or .js), only to directory-like URLs.
Query Strings: The regex pattern preserves query parameters during redirects.
Performance: The if-condition is evaluated for every request, but the overhead is minimal.
After implementing, verify with curl:
curl -I http://yourdomain.com/contacts
Should return:
HTTP/1.1 301 Moved Permanently Location: http://yourdomain.com/contacts/
If you need more control, consider this map-based solution:
map $request_uri $trailing_slash_redirect { default 0; "~^/[^?]*[^/]$" 1; } server { # ... if ($trailing_slash_redirect) { return 301 $uri/; } # ... }
This approach is more efficient when you have many location blocks.