Handling Cors Error with API resolver In NextJs

Handling  Cors Error with API resolver In NextJs

Introduction

What is the CORS error

A simple explanation of what causes CORS in the browser is when you are fetching resources from an external URL.

More Detailed Explanation Here.

CORS in NextJs

Having cors error in the front-end(client) is caused by:

  • The server not allowing the client to have access to the resources.
  • The client needs some set of configurations to do in the front end.

if the issue is from the formal, All we need to do is take a break till it is resolved from the server. else below are some of the ways to handle cors in NextJs.

  • Using NextJs Redirect.
  • Writing a resolver API in Nextjs.

    Using NextJs Redirect

    NextJs Redirect is equivalent to adding a proxy in a create-react-app(CRA) inside the package.json. For a simple example let's say the CRA is running on Port 3000.
"proxy": "http://localhost:4000",

A request to http://localhost:4000/login will be proxy into http://localhost:4000/login which will trick the browser to believe the request is from the same domain i.e http://localhost:3000/login.

In nextjs we can't put proxy in the package.json An equivalent approach is to create a next.config.js file in a nextjs project with this inside.

module.exports = {
  async rewrites() {
    return [
      {
        source: '/api/:path*',
        destination: 'http://localhost:4000/:path*'
      }
    ]
  }
}

source: this is where it will be redirected.

destination: this is the original path.

Using API Resolver.

After following the process in the formal and still encountering CORs Error. Another workaround approach is to create an interceptor in your NextJs to send the API request from the nextjs Server.

  • create a resolver.js in pages/api
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
//page/api/resolver.js
import axios from 'axios';

export default async function handler(req, res) {
  const { method, query } = req;
  const url = query.url;
  const config = {
    method,
    url,
  };

  try {
    const response = await axios(config);
    res.status(200).json(response.data);
  } catch (error) {
    const { response } = error;
    res.status(response?.status || 500).json(response?.data);
  }
}

before we test let's install Axios.

yarn add axios

an example request will be

http://localhost:3000/api/resolver?url=https://jsonplaceholder.typicode.com/todos/1

Screenshot from 2022-09-10 12-49-40.png for a POST or PUT request, we need to add a body field to the resolver.

  // Next.js API route support: https://nextjs.org/docs/api-routes/introduction

  import axios from 'axios';

  export default async function handler(req, res) {
    const { method, query, body, headers } = req;
    const url = query.url;
    const config = {
      method,
      url,
    };

    if (body) config.data = body;

    try {
      const response = await axios(config);
      res.status(200).json(response.data);
    } catch (error) {
      const { response } = error;
      res.status(response?.status || 500).json(response?.data);
    }
  }

for Authenticated requests we can intercept the authorization and add the auth token to the resolver.

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction

import axios from 'axios';

export default async function handler(req, res) {
  const { method, query, body, headers } = req;
  const token = headers?.authorization;
  const url = query.url;
  const config = {
    method,
    url,
  };
  if (token) {
    config.headers = {
      Authorization: token,
      ContentType: 'application/json',
    };
  }
  if (body) config.data = body;

  try {
    const response = await axios(config);
    res.status(200).json(response.data);
  } catch (error) {
    const { response } = error;
    res.status(response?.status || 500).json(response?.data);
  }
}

Conclusion

if the first one work for you, you may not necessarily go through the process of creating a resolver. let me know your opinion in the comment section. Thanks