How to Force Trailing Slashes in Nginx for Magento: 301 Redirect Solutions


2 views

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.