I’m moving a site from apache to nginx and stuck with the following configuration.
I have site http://example.com/ which shows the main (English) version.
Also, I have a few more languages which could be opened using correspondent subdirectories.
http://example.com/de http://example.com/fr, http://example.com/es or http://example.com/es/ (with a trailing slash).
These subdirectories are virtual (non-existing), but should open the same pages from the root directory. A php script handles the language representation.
Now English site works fine, however, other languages don’t work.
I can open http://example.com/es/ (only with a trailing char) and it opens the main page, however, all other pages could not be accessed (e.g. http://example.com/es/test.html which is a seo friend url). I already reviewed lots of similar questions and answers on SO but non of them are helpful.
Here is my configuration:
server {
....
root /var/www;
index index.php index.html index.htm;
location / {
rewrite ^/(de|fr|it|es)/(.*)$ /$2;
try_files $uri $uri/ @fallback;
}
location @fallback {
rewrite ^(.*)$ /seo.php?$args last;
}
location ~* .(jpeg|ico|jpg|gif|png|css|js|pdf|txt|tar|gz|wof|csv|zip|xml|yml) {
access_log off;
try_files $uri @static;
expires 14d;
add_header Access-Control-Allow-Origin *;
add_header Cache-Control public;
root /var/www;
}
location @static {
rewrite ^/(w+)/(.*)$ /$2 break;
access_log off;
rewrite_log off;
expires 14d;
add_header Cache-Control public;
add_header Access-Control-Allow-Origin *;
root /var/www;
}
location /backend/ {
rewrite ^(.*)$ /backend/index.php last;
}
location ~ .php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
It previously worked on apache as follows:
RewriteRule ^(de|fr|it|es)/(.*)$ $2
RewriteCond %{REQUEST_URI} !^/(backend|template)/
RewriteCond %{REQUEST_FILENAME} !.(gif|jpeg|png|js|css|swf|php|ico)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ seo.php [L]
2
Answers
Obviously Apache is transforming
/es
to/es/
before applying the rewrite.nginx
will not do that unless the directory actually exists.However, it is easily remedied by tweaking the regular expression, and making the trailing slash optional.
Try this:
The
(:? )
construct is a non capturing group.EDIT:
If you want the trailing slash to be added “visibly”, then you will need a redirect. For example:
Thank you so much @Richard Smith 🙂
I am using an Angular 13 app with an Nginx server for a Blog and the expected URL is –
My Nginx Configuration:
Inside blog folder-
The angular app needs to execute each request via index.html.
since the url structure is /blog/en — nginx expecting a folder ‘en’ inside ‘blog’.
but, these are virtual folder, which does not exists on the server.
hence we need to guide nginx that –
if users enter the url /blog — go to root folder ‘blog’ and run index.html.
if user enters the url /blog/some-file.css or some-file.js — go and check
if file exists in "blog" folder,
if yes, open it
else check if any folder exists with the same name in "blog" folder.
if yes, open it.
if all fails point that request to /blog/index.html.
now, there is no folder and files exists for the example request, /blog/en/a-beautiful-world
— nginx points that request to /blog/index.html as fallback and angular routes that request and execute with a proper modules, controller, etc.
—
Thanks