Every space has a story

CORS in NextJS

19 July 2021

Setting up CORS is always a challenge for people who are not really from server-side application backgrounds. Luckily it wasn’t the case for me, but Vercel.

I have a couple of projects on Vercel where I can host client-side applications built on ReactJS, NextJS, Gatsby, etc. Recently I found you can host serverless functions on Vercel as well.

These serverless functions are nothing but open up NodeJS server-side script access. You can create a server and run it on Vercel as well as send emails and whatnot.

How to setup NextJS API

npx create-next-app --example with-mongodb with-mongodb-app
# or
yarn create next-app --example with-mongodb with-mongodb-app

Example from with-mongodb

In the above command, you will get the NextJS project set up inside with-mongodb-app directory.

Now we have our application ready, it’s time to set up the MongoDB instance.

You can use mongodb.com to set up a free account with limited space.

MongoDB setup

Once you have your MongoDB instance ready, feel free to rename and edit env.local.example to .env.local

Set each variable on .env.local:

Run Next.js in development mode

npm install
npm run dev

# or

yarn install
yarn dev

The application should be up and running on http://localhost:3000

CORS setup

After setting up the database and server, now it’s time to set CORS settings.

Create vercel.json under the root folder.

{
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        { "key": "Access-Control-Allow-Credentials", "value": "true" },
        { "key": "Access-Control-Allow-Origin", "value": "*" }, // Change this to specific domain for better security
        {
          "key": "Access-Control-Allow-Methods",
          "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT"
        },
        {
          "key": "Access-Control-Allow-Headers",
          "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version"
        }
      ]
    }
  ]
}

The above change will work for GET requests but you will face problems while making PUT and POST requests. For this, we need to make one more change.

Go to /api/index.js file.

export default async (req, res) => {
  const { method } = req

  // This will allow OPTIONS request
  if (method === "OPTIONS") {
    return res.status(200).send("ok")
  }
}