0

I want to host the Angular i18n website using the Nginx proxy.

As per the official Nginx configuration suggestion https://angular.io/guide/i18n-common-deploy#nginx-example, my app.conf file in the /etc/nginx/site-available directory is like

map $http_accept_language $accept_language {
        ~*^de de;
        ~*^fr fr;
        ~*^en en;
}

server {
    listen 80;
    server_name i18n.example.io;
    root /var/www/html/app/dist/app;

    # Fallback to default language if no preference defined by browser
    if ($accept_language ~ "^$") {
        set $accept_language "en";
    }

    # Redirect "/" to Angular application in the preferred language of the browser
    rewrite ^/$ /$accept_language permanent;

    # Everything under the Angular application is always redirected to Angular in the
    # correct language
    location ~ ^/(fr|de|en) {
        try_files $uri /$1/index.html?$args;
    }
}

But when I try to access my website http://i18n.example.com, it gives the following error in the error.log file

2022/07/15 20:19:15 [error] 16886#16886: *1 rewrite or internal redirection cycle while internally redirecting to "/en/index.html", client: xx.xxx.235.xx, server: i18n.example.io, request: "GET /en HTTP/1.1", host: "i18n.example.io"
Anuj TBE
  • 111
  • 3

1 Answers1

0

can you modify try_files to try_files $uri /$1/index.html?$args =404;, restart nginx, and try again?

Not it gives 404 Not Found.

map $http_accept_language $accept_language {
    ~*^de de;
    ~*^fr fr;
    ~*^en en;
}

server {
    ...
    root /var/www/html/app/dist/app;

    ...
    if ($accept_language ~ "^$") {
        set $accept_language "en";
    }

according to your configuration, when you send requests to nginx with URL http://i18n.example.com, nginx will try to append language code (en/fr/de) according to Accept-Language HTTP header sent by your user agent. when there's no such header exists, nginx will by default append en language code.

    rewrite ^/$ /$accept_language permanent;
    location ~ ^/(fr|de|en) {
        try_files $uri /$1/index.html?$args;
    }

nginx then does an internal redirect to http://i18n.example.com/<language code> and evaluates location ~ ^/(fr|de|en) successfully.

for example, let's use en language code, so then the internal redirect points to http://i18n.example.com/en.

using this URI and your try_files $uri /$1/index.html?$args configuration, nginx will try to access http://i18n.example.com/en and http://i18n.example.com/en/index.html?<argument>; which translates to /var/www/html/app/dist/app/en and /var/www/html/app/dist/app/en/index.html respectively.

if no such file exists, which is happening in your current situation, your location ~ ^/(fr|de|en) will be re-triggered again since there's two requests to /en. this will create redirection loop inside nginx and it'll break out from the loop by sending an error.

to solve this, either check if you have /var/www/html/app/dist/app/en/index.html file available and readable by nginx, or add =404 to your try_files configuration to let it gracefully fail as 404 error.

mforsetti
  • 2,488
  • 2
  • 14
  • 20