# Redirect to the original URL inside a Remix action

Let's say the user is currently at the URL `/:username`, and there's a button to follow that user (like in a Twitter profile page).

```tsx
function View() {
  let { profile } = useRouteData<{ profile: { name: string, id: string }}>()
  return (
    <div>
      <h1>{profile.name}</h1>
      <Form method="post" action={`/users/${profile.name}/follow`}>
        <input type="hidden" value={profile.id} name="userId" />
        <button type="submit">Follow</button>
      </Form>
    </div>
  );
}
```

After the user submit our form inside our action we will receive the `profile.id` and then we need to redirect the user to another URL, but we want the user to redirect back to the URL the user was when it clicked the Follow button.

```ts
export let action: ActionFunction = async ({ request }) => {
  let body = await parseBody(request);
  let session = await getSession(request.headers.get("Cookie"));
  await followUser(body.get("userId"), session.get("token")); // imagine this create a new follow in the DB
  return redirect("?");
}
```

So how can we do this? There's a few ways.

## Using the parameters

In that example in particular we can get the `profile.name` from the `params`, so we could do:

```ts
export let action: ActionFunction = async ({ request, params }) => {
  // the code from the first example, removed for simplicity
  return redirect(`/${params.name}`);
}
```

This will work in this case but it may not if the URL of the action was simply `/like` or something without any parameter in the middle

## Pass the original URL inside the form

Another option is to send the URL we want to redirect the user to after the action inside the body of the action.

```tsx
function View() {
  // we get the full URL from the loader, in the loader we can just return `request.url`
  let { profile, url } = useRouteData<{ profile: { name: string, id: string }, url: string }>()
  return (
    <div>
      <h1>{profile.name}</h1>
      <Form method="post" action={`/users/${profile.name}/follow`}>
        <input type="hidden" value={url} name="redirectTo" />
        <input type="hidden" value={profile.id} name="userId" />
        <button type="submit">Follow</button>
      </Form>
    </div>
  );
}
```

Then in the action:

```ts
export let action: ActionFunction = async ({ request, params }) => {
  // the code from the first example, removed for simplicity
  return redirect(body.get("redirectTo"));
}
```

And again that will work, we can be sure to always send that `redirectTo` value and this can be a nice pattern to follow everytime you need this.

## Use the Referer HTTP header

The HTTP header `Referer` is a way the browser can send to a server the URL the user was coming from. We can get it from the `request` inside the action and use it to get the exact URL the user was before the submit.

```ts
export let action: ActionFunction = async ({ request, params }) => {
  // the code from the first example, removed for simplicity
  return redirect(request.headers.get("Referer"));
}
```

We can build a simple wrapper called `redirectBack` and pass the request and make the wrapper read the header for us. This is what I did for my [`redirectBack` function in Remix Utils](https://github.com/sergiodxa/remix-utils#redirectback) so you can just do:

```ts
export let action: ActionFunction = async ({ request, params }) => {
  // the code from the first example, removed for simplicity
  return redirectBack(request);
}
```

The main problem with this way of doing the redirect is the Referer header may not be present, e.g if the user defined the CSP header `Referrer-Policy: no-referrer` then from that page the browser will never send the Referer to any request. So for those cases we will need a fallback, the `redirectBack` function receives it as a second value:

```ts
export let action: ActionFunction = async ({ request, params }) => {
  // the code from the first example, removed for simplicity
  return redirectBack(request, { fallback: "/something" });
}
```

This way we can define a URL we are ok if the user is redirected to even if it's not the same, an example of this  could be if we wanted to preserve search params we can use the Referer header to get them but as a fallback use the URL without search params.

If we combine this with the `redirectTo` inside the form body we can have something like this:

```ts
export let action: ActionFunction = async ({ request, params }) => {
  // the code from the first example, removed for simplicity
  return redirectBack(request, { fallback: body.get("redirectTo") });
}
```