A simple setup for using nginx as a local reverse proxy to avoid Cross-Origin Resource Sharing (CORS) errors during frontend development (React, Angular etc.) without the need of code changes.
Going ahead with some modern browser-side rendered frontend development 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…
Table of Contents
Local development 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 or Angular application
|
+-- /api => backend e.g. Node.js Express server
Without a doubt that would run fine in production. But during your local development there’s a little 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 or Angular, this would result in ending up with the following error message for every request made from the frontend to the backend:

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 – details see below. 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 programmatically
So the most obvious solution is simply to enbale CORS by setting the respective headers in the response from the backend. There are also many libs for doing that and it’s no big deal.
If you want to do it manually, you’ll have to set three response header values – Access-Control-Allow-Origin, Access-Control-Allow-Headers, Access-Control-Allow-Methods – as shown in the example above. Here, a simple middleware function is used assuming your backend is a Node.js Express server – works with any other backend technique as well.
// set this middleware to set CORS headers before sending any backend response
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', '*');
res.setHeader('Access-Control-Allow-Methods', '*');
next();
});
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 reverse 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 deployments.
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 proxy localhost/
to localhost:3000
and localhost/api/
to localhost:3030
using the proxy_pass directive. 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 🙂