We had a situation where a client using Joomla wanted to have trailing slashes added to URLs, not just processed behind the scenes as the ‘correct’ URL but 301ed to the resulting URL with the trailing slash.
This makes sense from a SEO standpoint as you don’t want two URLs with the same content. Joomla was expecting trailing slashes as well and wasn’t properly processing URLs without them.
We also wanted to avoid “If” statements inside our NginX configurations as they are processed in a difficult to predict manner, are inefficient and are generally considered to be evil.
As some background with Joomla we use a configuration like this so that files that exist are served, but anything else is re-mapped (with no redirect) to Joomla’s index.php. This is commonly referred to as “SEO friendly URLs”:
location / { try_files $uri $uri/ /index.php$is_args$args; }
Adding the 301 redirects with trailing slashes is actually quite simple: We catch candidate URLs in their own location block, see if the file really exists, and if not jump to a custom @location destination which does the 301:
location ~ ^([^.\?]*[^/])$ { try_files $uri @addslash; } location @addslash { return 301 $uri/; } location / { try_files $uri $uri/ /index.php$is_args$args; }
To recap: We define a “location ~ ^([^.\?]*[^/])$” at the top that matches all URLs that don’t have a period in them and that don’t end in a slash (so http://www.site.com/file.php will not match – even if it doesn’t exist). This first location block’s “try_files” statement checks to see if the URL maps to a file that exists, and if not @addslashes is triggered.
Then we define the @addslashes location to return a 301 using the URI with a slash at the end as the new destination.
Lastly we keep the original “location /” block to preserve the re-mapping functionality for any URLs not like this (or, for example, have already been redirected previously).
thank you, man!!!
Finally an easy but working solution, thanks!
Thank you so much. Been looking for this solution for so many hours!!