Add trailing slash when it's missing in nginx
Solution 1
I've found the solution: I added the following line above the "try_files" directive in the "location /"-block:
rewrite ^([^.]*[^/])$ $1/ permanent;
which does the magic.
Solution 2
This is very, very tricky because you have to consider all possibilities in your URLs. Let's have a closer look at that configuration you posted there and optimize it while trying to implement your wish. I have to correct the complete configuration because it contains more than one security risk for your website (and continue reading after the configuration).
server {
server_name DOMAIN.com;
return 301 $scheme://www.$server_name$request_uri;
}
server {
index index.html index.php;
listen 80 default;
root /var/www;
server_name www.DOMAIN.com;
location / {
# Hide ALL kind of hidden stuff.
location ~ /\. {
return 403;
}
# Protect Magento's special directories in document root.
location ~* ^/(app|includes|lib|media/downloadable|pkginfo|report/config\.xml|var)/? {
return 403;
}
# Directly deliver known file types.
location ~* \.(css|gif|ico|jpe?g|js(on)?|png|svg|webp)$ {
access_log off;
add_header Cache-Control "public";
add_header Pragma "public";
expires 30d;
log_not_found off;
tcp_nodelay off;
try_files $uri =404;
}
# Do not allow direct access to index.php
location ~* ^(.*)index\.php$ {
return 301 $1;
}
# Extremely risky ... oh boy!
location ~* \.php/ {
rewrite ^(.*\.php)/ $1 last;
}
# Not direct index.php access and not one of those ultra
# risky php files with a path appended to their script name,
# let's try to add a slash if it's missing.
location ~* ^(.*)[^/]+$ {
return 301 $1/;
}
location ~* \.php$ {
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param MAGE_RUN_CODE "default";
fastcgi_param MAGE_RUN_TYPE "store";
fastcgi_pass 127.0.0.1:9000;
# Ensure it's an actual PHP file!
try_files $uri =404;
}
}
location ^~ /var/export/ {
auth_basic "Restricted";
auth_basic_user_file htpasswd;
autoindex on;
}
}
IMPORTANT! IMPORTANT! IMPORTANT! IMPORTANT!
I can't test this configuration, I've written it down to my best knowledge. Please execute nginx -t
before attempting to reload
your nginx and report back if this reports any errors. Do not, I repeat, do not test this on your production site and test everything you can think of.
vincent.io
I'm an Entrepreneur and Product Designer, combining my backgrounds in design, business and software development to build products that deliver great experiences. I'm cofounder and CEO at Content Optimization service ContentKing. Apart from ContentKing I am the chairman of C-Squared, a non-profit organization based in Brno, Czech Republic that connects companies to local tech communities. From time to time I dabble in code and build robots. The first robot I ever built committed suicide by taking the stairs. I fixed that bug in the second revision, but it didn’t do much more than avoiding stairs. Originally from The Netherlands, I'm currently living in Brno, Czech Republic. In my spare time I love running, reading and hiking. On top of that I have a passion for aviation, and hope to fly my own HondaJet one day.
Updated on September 18, 2022Comments
-
vincent.io over 1 year
I'm running Magento on Nginx using this config: http://www.magentocommerce.com/wiki/1_-_installation_and_configuration/configuring_nginx_for_magento.
Now I want to 301 all URLs without trailing slash to their counterpart that includes a trailing slash. For example: /contacts to /contacts/.
I've tried virtually all the nginx directives on this I could find, but to no avail. For example, the directive specified in nginx- Rewrite URL with Trailing Slash leads to a redirect to /index.php/.
Which directive should I add and where?
-
vincent.io over 10 yearsThank you for your answer, but that doesn't solve my problem.
-
DanCat almost 7 yearsCould you go into detail on the behavior of the regex?
-
helb over 6 years@DanCat Something like "group of any number of non-period characters not followed by a slash"