nadiTime
nadiTime

Reputation: 173

remix return redirect from action function called by browser fetch

Is it possible to redirect from an action function when you posted to it using fetch instead of Form or useSubmit?

example: (this doesn't work...)

export const action: ActionFunction = async ({ request }) => {
  const data = await request.json();
  return redirect(`${data.redirectTo}`);
};

const Component = () => {
  useEffect(() => {
    const timer = setTimeout(async () => {
      const data = { redirectTo: "/home" };
      await fetch("test", {
        method: "POST",
        body: JSON.stringify(data),
      });
    }, 2500);
    return () => clearTimeout(timer);
  }, []);
  return (
    <div>
      ...
    </div>
  );
};

export default Component;

I can see in the network tab the new GET /home but there is no actual redirect

Upvotes: 1

Views: 1510

Answers (1)

Nullndr
Nullndr

Reputation: 1827

When you return a redirect Response from an action you won't be redirected from the action itself, but rather from the component or hook that made the request (the same applies for loader).

In your case you could simply use a fetcher:

export const action: ActionFunction = async ({ request }) => {
  const data = await request.formData();
  return redirect(data.get("redirectTo") as string);
};

const Component = () => {
  const fetcher = useFetcher();

  useEffect(() => {
    const timer = setTimeout(async () => {
      const data = { redirectTo: "/home" };
      fetcher.submit(data, { method: "post" });
    }, 2500);
    return () => clearTimeout(timer);
  }, []);
  return (
    <div>
      ...
    </div>
  );
};

I can see in the network tab the new GET /home but there is no actual redirect

Sure there is, this is how the redirect response works!

Try to console.log the status from the response:

const response = await fetch("test", {
  method: "POST",
  body: JSON.stringify(data),
});

console.log(response.status); // 200, not 302

When fetch gets a redirect response, automatically forge a new request to the redirection url, this is why you see a get to /home.

But once that fetch get the response from /home what will happen?

Nothing, fetch has no clue on how to treat this response.

This is why you aren't redirected to /home with fetch.

Upvotes: 1

Related Questions