back to blog

Fixing Third-Party Redirects in JavaScript: Why window.location Beats fetch()

Written by Namit Jain·April 30, 2025·2 min read

This post covers a subtle but frustrating redirect bug I recently ran into while working on a payment integration.

The Problem

I was generating a payment URL from my backend (using FastAPI), which pointed to a third-party payment gateway.

From the frontend, I made a POST request using fetch() and then tried to redirect the user like this:

const response = await fetch("/api/create-payment", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ amount: 100 }),
});

const data = await response.json();
window.location.href = data.redirect_url;

The URL looked fine. When I pasted it directly into the browser, it worked. But when the code redirected the user, the third-party page didn't behave correctly.

What's Going On?

This happens because of how fetch() handles redirects:

  • When a redirect occurs (like a 302), fetch() will follow it internally.
  • However, it doesn't cause the browser to actually navigate to the new URL.
  • Cookies, headers, and browser context may not carry over properly.
  • Some third-party services won't work correctly unless the browser performs the redirect directly.

The Fix

Instead of using fetch(), I let the browser handle the redirect:

window.location.href = `/api/create-payment?amount=100`;

And on the backend:

from fastapi.responses import RedirectResponse

@app.get("/api/create-payment")
def create_payment(amount: int):
    redirect_url = generate_third_party_url(amount)
    return RedirectResponse(url=redirect_url, status_code=302)

This worked as expected. The browser performed a clean, full-page redirect with all the right context.

When to Use This

Use this pattern when:

  • Redirecting to third-party URLs (payments, OAuth, etc.)
  • You want browser-level handling of cookies, headers, or session
  • The third-party page doesn't load properly after a fetch()-initiated redirect

Takeaway

Avoid using fetch() when the goal is to navigate the user to a third-party page. Use window.location.href or window.open() instead, and let the browser do what it's designed to do.