I have a simple website with some PHP files in two languages: the main language and the translation, let's say Spanish.
I want to show a 404 error page for the main language if someone tries to load an non-existing URL, and a translated 404 error page for non-existing URLs in the /es subdirectory.
This is my config file:
server {
listen 80;
server_name example.com;
root /var/www/example.com;
location / {
error_page 404 /404.php;
try_files $uri $uri/ @extensionless-php;
index index.php;
}
location /es {
error_page 404 /es/404.php;
try_files $uri $uri/ @extensionless-php;
index index.php;
}
location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location @extensionless-php {
rewrite ^(.*)$ $1.php last;
}
}
It is not working as expected. When loading a non-existing URL (whether in the root or in the /es subdirectory) nginx returns the standard 404 page (the one displaying 404 Not Found).
If I add error_page 404 /404.php; in the server block (outside location blocks), then example.com/foo and example.com/es/foo would return the non-translated 404 error page.
How can I fix this?
CodePudding user response:
Any of your requests for the non-existent resources ends up at the location ~ \.php$ { ... } block where you do not have error_page directive at all. If you define your custom error page at the server level, that location inherits that page. You can define two PHP handlers (order of location blocks matters!):
location ~ ^/es. \.php$ {
error_page 404 /es/404.php;
... # other content is the same as in the question
}
location ~ \.php$ {
error_page 404 /404.php;
... # other content is the same as in the question
}
or better use a map block like
map $uri $errpage {
~^/es /es/404.php;
default /404.php;
}
server {
...
error_page 404 $errpage;
}
