Skip to main content

Handling Redirects in the midle of the request chain

ยท 3 min read
Pere Pages
handling redirects

When working in a React application with API calls, handling redirects in the middle of the request chain can be tricky.

scenario

When you make an API call from your frontend code to your server, and the server then makes another request that returns a redirect.

  Frontend (React)         Backend (Your server)          2nd API (External)       3rd API (Redirects for auth)

GET request ---------------> | | |
|------ GET request ------>| |
| |----- GET request ------>|
| | |
| | 302 Redirect
| |<------------------------|
| Capture 302 & try to | |
| follow redirect | |
| | |
| 500 Error | |
500 Error <------------------| | |

Your server must handle the redirect appropriately and pass it back to your frontend application.

Solutionโ€‹

  Frontend (React)         Backend (Your server)          2nd API (External)       3rd API (Redirects for auth)

GET request ---------------> | | |
|----- GET request ------->| |
| |------ GET request ----->|
| | |
| | 302 Redirect
| |<------------------------|
| Capture 302 and send | |
| back to Frontend | |
Redirect URL <---------------| | |
| | |
Browser performs | | |
the actual redirect -------->| | |

Backend Changesโ€‹

On your server-side code, when your server makes the API call that returns a redirect, you should capture that redirect URL and send it back to the frontend in a custom header or within the response body.

For example, in a Node.js Express backend:

import axios from "axios";

app.get("/your-endpoint", async (req, res) => {
try {
const response = await axios.get("another-api-endpoint", {
maxRedirects: 0,
});
} catch (error) {
if (error.response && error.response.status === 302) {
const redirectUrl = error.response.headers.location;
res.status(200).send({ redirectUrl });
}
}
});

Frontend Changesโ€‹

In your frontend, after receiving this custom header or response body, you can then perform the actual redirect.

import axios from "axios";
import { useEffect } from "react";

const fetchData = async () => {
const response = await axios.get("/your-endpoint");
if (response.data.redirectUrl) {
window.location.href = response.data.redirectUrl;
}
};

const App: React.FC = () => {
useEffect(() => {
fetchData();
}, []);

return <div>{/* Your App */}</div>;
};

export default App;

Using Axios Interceptorsโ€‹

If you use Axios in your frontend code, you can use Axios interceptors to intercept the response and check if it contains a redirect URL.

axios.interceptors.response.use((response) => {
if (response.data.redirectUrl) {
window.location.href = response.data.redirectUrl;
}
return response;
});

This way, you can ensure that whenever your backend sends a redirectUrl, the frontend application redirects the user to that URL. This should help you with the 500 error that you see in the network console, as the actual redirection is then done in the browser, thus retaining the browser context needed for permissions or authentication.