ExpressExtra· 35 min read

CORS, Env Vars & Connecting React

The final pieces to connect your React front-end to your Express back-end — across origins, with secrets kept safe.

What you will learn

  • Enable CORS so the browser can call your API
  • Keep secrets in environment variables
  • Connect a React front-end to the API

CORS: let the browser call your API

When your React app (e.g. localhost:5173) calls your API (localhost:3000), the browser blocks it by default — a different port counts as a different "origin", and browsers refuse cross-origin requests for safety. CORS (Cross-Origin Resource Sharing) is the server’s way of saying "I allow this". The cors middleware adds that permission for you. First install it:

Install cors
npm install cors

Note: Output: added 1 package in 1s This downloads the cors package into node_modules/ and records it in package.json, so you can now require it.

Then turn it on as middleware near the top of your app, so it applies to every route:

Enable CORS in your Express app
const cors = require("cors");
app.use(cors());   // allow cross-origin requests

Note: Output: (no visible output — it works silently) app.use(cors()) adds a response header that tells the browser "requests from other origins are welcome". Without it, your React app’s fetch would fail with a CORS error in the browser console, even though the server itself is fine.

Environment variables

Never hard-code secrets (database URLs, API keys) in your code — if you push that to GitHub, the whole world can read them. Instead put them in a special .env file, read them with the dotenv package, and add .env to .gitignore so it is never committed. The file is just KEY=value lines:

.env (never commit this)
# .env
PORT=3000
MONGO_URI=mongodb://localhost:27017/myapp

Note: Output: (this is a config file, not a program) Each line defines one setting: a PORT to run on and a MONGO_URI database address. Keeping these out of your code means you can use different values on your laptop and on the live server without changing a single line of JavaScript.

Now load them at the very top of your app. dotenv copies every line from .env into process.env, where your code can read them:

Read env vars with dotenv
require("dotenv").config();
const PORT = process.env.PORT || 3000;

Note: Output: (no output — it sets up values for later use) require("dotenv").config() reads the .env file and loads its values into process.env. Then process.env.PORT gives you the 3000 from the file. The || 3000 is a safety fallback: if PORT is somehow missing, it uses 3000 anyway so the app still runs.

The React side

Finally, the front-end. This is the same fetch you already learned, now pointed at your own Express API instead of someone else’s. It runs once when the component loads (useEffect with an empty []) and stores the result in state:

React fetches from your own Express API
// In your React component
useEffect(() => {
  fetch("http://localhost:3000/tasks")
    .then(res => res.json())
    .then(setTasks);
}, []);

Note: Output: The React component receives the tasks array from your API and renders it on screen. Reading it: useEffect(() => {...}, []) runs once after the component first appears. fetch("http://localhost:3000/tasks") calls your Express GET route; .then(res => res.json()) turns the response into a JavaScript array; .then(setTasks) saves it into state so React re-renders with the data. This only works because the server has CORS enabled.

The full round trip

Putting the whole stack together, here is what happens when the page loads:

  1. React mounts and useEffect fires a fetch to http://localhost:3000/tasks.
  2. The browser checks CORS — your server allows it, so the request goes through.
  3. Express matches the GET /tasks route and (soon, with MongoDB) gathers the data.
  4. Express sends the data back as JSON.
  5. React turns that JSON into an array with res.json() and stores it with setTasks, re-rendering the UI.

Tip: This is the full circle: React fetch → Express route → (soon) MongoDB → JSON back to React. You already know every piece; CORS and env vars are the glue.

Q. Why do you need CORS on your Express API?

Answer: Browsers block cross-origin requests by default. The cors middleware tells the browser your API permits requests from your front-end’s origin.

✍️ Practice

  1. Add cors() to an API and fetch it from a React app on a different port.
  2. Move your port and a secret into a .env file and read them with dotenv.

🏠 Homework

  1. Connect a small React app to your Express API and display the data.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →