ReactHustle

How to Send POST Request to External API in NextJS

Jasser Mark Arioste

Jasser Mark Arioste

How to Send POST Request to External API in NextJS

It's very common nowadays in a microservice architecture that our web apps call data from several external APIs. You might have one API that handles notifications, or CRUD operations for orders and such. 

In this tutorial, you'll learn how to send a POST request to an external API in NextJS. You'll also learn how to use NextJS as a proxy to avoid CORS errors and increase the security of your app.

Problem - CORS Error when POST to External API #

Suppose you are running two apps locally. One is a backend REST API that handles CRUD operations and one is a frontend web app that handles the user interaction.

This is an extremely common architecture nowadays.

The backend API endpoint is running at localhost:3001 and your frontend app is running at localhost:3000.

You try to send a POST request to your backend API like the one below:

// component/Todos.tsx
import React from "react";
import { useState } from "react";
const Todos = () => {
  const [description, setDescription] = useState("");
  const addTodo = () => {
    // 👇 Send a fetch request to Backend API.
    fetch("http://localhost:3001/api/todos", {
      method: "POST",
      body: JSON.stringify({
        description,
      }),
      headers: {
        "content-type": "application/json",
      },
    }).catch((e) => console.log(e));
  };

  return (
    <div>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          addTodo();
        }}
      >
        <input
          name="description"
          placeholder="Add new todo..."
          value={description}
          onChange={(e) => setDescription(e.target.value)}
        ></input>
        <button type="submit">Add todo</button>
      </form>
    </div>
  );
};

export default Todos;
123456789101112131415161718192021222324252627282930313233343536373839

But when you click "Add todo", it fails due to a CORS error:

Access to fetch at 'http://localhost:3001/api/todos' from origin 'http://localhost:3000' has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
12

How do you fix this without modifying the backend server (localhost:3001)?

Solution - Modify next.config.js to use rewrites #

One way to easily fix this is to modify next.config.js and use rewrites, for example: 

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  swcMinify: true,
  async rewrites() {
    return [
      {
        source: "/api/todos",
        destination: "http://localhost:3001/api/todos",
      },
    ];
  },
};
module.exports = nextConfig;
123456789101112131415

Explanation:

First, we add a source path: /api/todos. now all requests to the /api/todos route will pass through our frontend server which then forwards the request to our backend server. The Browser will think that it's requesting from the same origin which ultimately solves the CORS problem.

Also, note that you have complete control of the source path. You can even use source: "/my_external_api" to avoid misunderstandings.

Next, Let's modify our component to use /api/todos instead of localhost:3001/api/todos.

// components/Todos.tsx
import React from "react";
import { useState } from "react";
const Todos = () => {
  ...
  const addTodo = () => {
    // 👇 Send a fetch request to Backend API
    fetch("/api/todos", { // "/my_external_api" as an alternative
      method: "POST",
      ...
    }).catch((e) => console.log(e));
  };
  ...
}
1234567891011121314

Now, when we send the POST request, there's no CORS error, and returns the correct status code:

Next JS Successful POST request to External API

Conclusion #

We learned how to send a request to an external API in NextJS and avoid CORS errors. Another benefit of using this technique is it hides the backend endpoint from the end users. Even if they check the network tab, they'll only see "/api/todos" and this increases the security of your app.

If you like this tutorial, please leave a like or share this article. For future tutorials like this, please subscribe to our newsletter.

Credits: Image by Leng Kangrui from Pixabay

Share this post!

Related Posts

Disclaimer

This content may contain links to products, software and services. Please assume all such links are affiliate links which may result in my earning commissions and fees.
As an Amazon Associate, I earn from qualifying purchases. This means that whenever you buy a product on Amazon from a link on our site, we receive a small percentage of its price at no extra cost to you. This helps us continue to provide valuable content and reviews to you. Thank you for your support!
Donate to ReactHustle