nginxnext.js

How to deploy Next.js static export with Nginx? (deep links not working)


I made a next.js export into the out folder.

Folder structure is:

I set up nginx to serve files from this folder:

server {
    root /var/www/myproject/out;
    index index.html index.htm index.nginx-debian.html;

    server_name myproject.com;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

The main page (index) opens fine. Navigation from within the app to urls like myproject.com/privacy works fine. The problem is if I try to open these links directly, it will serve the main page (index) instead of the actual pages, since those urls don't exist in the folder. The only way to open the privacy page directly is adding the html extension to the url: myproject.com/privacy.html.

How to configure nginx to serve the actual page myproject.com/privacy.html when someone enters the myproject.com/privacy url?


Solution

  • Issue is in try_files.

    As current configuration includes:

    To access pages route path name without extension i.e., /privacy that format should be included in try_files insdie location /

    Try this:

    try_files $uri $uri.html /$uri /index.html
    

    Little explanation

    The try_files directive in the nginx.conf file is used to specify how Nginx should handle requests for files. The directive attempts to serve files in the order they are listed, and if none of the specified files are found, it falls back to the last option.

    In the provided code, try_files $uri $uri.html /$uri /index.html;, Nginx will follow these steps when a request is made:

    It first tries to serve the file that matches the requested URI ($uri). For example, if the request is for /about, Nginx will look for a file named about. If the file is not found, it then tries to serve a file with the .html extension appended to the requested URI ($uri.html). So, for the /about request, it will look for about.html.

    If neither of the above files is found, it tries to serve the file by prepending a / to the requested URI (/$uri). This step is somewhat redundant in this context and might be a misconfiguration.

    Finally, if none of the previous files are found, it falls back to serving index.html. This is a common practice in single-page applications (SPAs) where all routes are handled by a single HTML file. This configuration is particularly useful for SPAs built with frameworks like React, where client-side routing is used, and all routes should be served by the same index.html file.