Redirecting back to the referring page?

I have a link to a controller that does some work, but doesn’t need to display a page. Instead, I’d like it to return to the referring page (defaulting to “/”) with a flash message. I found out (on StackOverflow) that I can get the referring URL as follows:

List.keyfind(conn.req_headers, "referer", 0)

This gives me a tuple such as:

{ "referer", "http://localhost:4000/item?key=..." }

I can easily extract a URL string such as /item?key=..., but the redirect function wants a “page path”. Looking at the routing page, I don’t see any functions that will generate a page path from a URL.

I did find this solution, but it seems extremely convoluted. Help?

Do not rely on the referer, browser or other kind of software might not set it.

Instead a its common to simply have a query parameter back_to=old_url, of course you can set old_url to anything you want.

An even better solution I think though, were to make this endpoint available as API only, use JS top trigger the work and display the message. Or trigger the job through a channel and reply with a started message and even later with a “success” or “fail”.

To complement what @NobbZ suggested, I would use a parameter. Here’s an example where I have to different froms submitting to the same controller action:

  def update(conn = %{assigns: %{cart: cart}}, %{"id" => id, "line_item" => line_item_params}) do
    id
    |> Estimates.get_line_item!()
    |> Estimates.update_line_item!(line_item_params)

    redirect_to =
      case conn.params["redirect"] do
        nil ->
          telesales_cart_product_path(conn, :index, cart)
        path ->
          path
      end

    conn
    |> put_flash(:info, dgettext("carts", "Item saved successfully."))
    |> redirect(to: redirect_to)
  end

In this case, I’m looking for a param called redirect. If it’s found, I redirect to its value, otherwise I go to the default location.

I use Navigation History to achieve this. Give it a try.

1 Like

Thanks, all! FWIW, I opted to go with the redirect parameter, which I set (in app.html.eex) as follows:

redirect = "/#{ @conn.path_info }?#{ @conn.query_string }"

Navigation History looks pretty cool; I may use it in the future to help users figure out where they’ve been, etc.