nginx

Nginx - multiple/nested IF statements


What I want to do:

It is a single page app. Before my changes configuration looked like this (and it worked):

location / {
    root /home/eshlox/projects/XXX/project/project/assets/dist;
    try_files $uri $uri/ /index.html =404;
}

I've tried to use if statements:

location / {
    set $social 1;
    if ($http_user_agent ~* "facebookexternalhit") {
        set $social UA; 
    }       
    if ($uri ~* "^/(\d+)$") {
        set $social "${social}URL";
    }       
    if ($social = UAURL) {
        rewrite ^/(\d+)$ /api/content/item/$1?social=1;
    }

    root /home/eshlox/projects/XXX/project/project/assets/dist;
    try_files $uri $uri/ /index.html =404;
}

With this configuration everything works as I expected only if both conditions are true or false. If one of conditions is true and the second is false (or vice versa) then nginx always returns status 404.

I have found "IfIsEvil" on nginx site, I've tried to use mapping (can I use mapping in this case?), but still I can't resolve this problem.

Any ideas?


Solution

  • There is good article about common pitfalls in nignx wiki.

    First, I've moved root directive to server level. Second, location is the best way to check urls. So I rethink your requirements as

    we have to rewrite url, and the result is:

    root /home/eshlox/projects/XXX/project/project/assets/dist;
    
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    location ~ "^/\d+$" {
        if ($http_user_agent ~* "facebookexternalhit") {
            rewrite (.+) /api/content/item$1?social=1;
        }
    
        try_files $uri $uri/ /index.html;
    }
    

    Also, there is almost no reason to have =404 after /index.html in try_files directive.