nginx as development proxy to avoid CORS errors

A simple setup for using nginx to avoid CORS errors during local development without the need of code changes.

Going ahead with some modern browser-side rendered frontend development (e.g. React) you may very quickly face the following issue: splitting your project into frontend and backend solutions, you’ll very likely end up in facing CORS errors during development. Let’s have a closer look on that…

Local dev situation

Let’s assume you are developing a frontend and a backend service belonging together. It’s a good practice to have those two projects separated to decouple development, deployment, patching etc.

At the end, both parts mostly would run under one domain but in different contexts, e.g.:

https://mydomain.com
|
+-- /      => frontend e.g. React
|
+-- /api   => backend e.g. NodeJS

Without a doubt that would run fine in production. But during your local development there’s a liitle gotcha: you cannot start both projects binding to the same port.

So you’ll have bind to different ones like so:

http://localhost
|
+-- :3000/     => frontend
|
+-- :3030/api  => backend

Developing a modern client-side web frontend, like with React, this would result in ending up for every request made from the frontend to the backend with the following error message:

cors-error-localhost

This is because modern browsers don’t allow cross origin requests until they are explicitly allowed by the called service which is indicated by the mentioned header. Note: the port is part of the “origin”, so localhost:3000 is a different origin then localhost:3030 although it’s both located on localhost.

Solution 1 (bad): enable CORS

So the most obvious solution is simply to enbale CORS by setting the respective header in the response from the backend. There are many libs for doing that and it’s no big deal.

Anyways, it’s a bad solution because you would invoke code changes for your local development that are absolutely not necessary and not wanted for production use. Remember, once all projects are deployed under the exactly same URL in production, no CORS error will occur anyways.

Solution 2 (good): use nginx as a development proxy

The by far better solution is to set up a small local proxy to avoid CORS on different ports of localhost. nginx is perfect for this, the setup is very simple. Furthermore this solution would be a kind of simulated production environment as there will mostly be exactly the same setup with some kind of “proxy” in front of your deployment.

To set up nginx as a local proxy for the abovementioned development scenario you simply have to put the following server-block into your nginx.conf normally located under /etc/nginx (get rid of any other pre-defined stuff in that section).

server {
  listen 80;
        
  location / {
    proxy_pass http://localhost:3000;
  }

  location /api {
    proxy_pass http://localhost:3030;
  }
}

This binds nginx to port 80 and would redirect localhost/ to localhost:3000 and localhost/api/ to localhost:3030. That resolves any CORS issue because now both services, frontend and backend, can be called with the same origin.

Any request from the frontend to /api will not cause errors in your browser any more.

You can now access your web frontend via http://localhost/ without having any trouble with requests to your backend.

Happy coding 🙂