Create React App Push State Nginx Config

I learned today that Create-react-app’s production build needs to sit behind a HTML5 pushstate enabled server (the build script drops a hint recommending the pushstate-server npm package). The reasoning here is if you make a request for https://johnbrett.me/user/123, nginx (or most web servers) will look for a file inside your apps root directory, for a user directory containing the file 123.

Below is the nginx config to replicate pushstate-server’s functionality, but through nginx. This cost me some time to figure out, so posting it here so I remember in future and to be of use to anyone else who hit this issue.

Default Server Configuration

server {
  listen 80 default_server;

  server_name johnbrett.me;

  root /var/www/app;

  # Routes without file extension e.g. /user/1
  location / {
    try_files $uri /index.html;
  }

  # 404 if a file is requested (so the main app isn't served)
  location ~ ^.+..+$ {
    try_files $uri =404;
  }

  # OPTIONAL: For an API server you want to proxy
  location /api {
    proxy_pass [http://localhost:8081](http://localhost:8081);
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection ‘upgrade’;
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }

}

You can test the config with the following:

$ sudo nginx -t

And restart the nginx server with:

$ sudo systemctl restart nginx

This was useful: https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-16-04