phoenix_live_view icon indicating copy to clipboard operation
phoenix_live_view copied to clipboard

mailto link in redirect causes live view to disconnect

Open Flo0807 opened this issue 1 year ago • 2 comments

Environment

  • Elixir version (elixir -v): 1.16.2
  • Phoenix version (mix deps): 1.7.14
  • Phoenix LiveView version (mix deps): 0.20.17
  • Operating system: macOS
  • Browsers you attempted to reproduce this bug on (the more the merrier): Brave, Safari
  • Does the problem persist after removing "assets/node_modules" and trying again? Yes/no: yes

Actual behavior

An (external) redirect to a mailto link causes the LiveView to disconnect.

In my application I have a handle_event that handles a button click and redirects to a mailto link. After clicking the button, the LiveView is disconnected and I have to refresh the page.

def handle_event("link", _params, socket) do
  {:noreply, redirect(socket, external: "mailto:[email protected]")}
end

Here is an example of a single file that reproduces the problem: https://gist.github.com/Flo0807/900312c41b34188901bb22971cce5d18 (note that the + and - buttons no longer work after clicking the "Link" button)

Expected behavior

A redirect to a mailto link should not cause the LiveView to diconnect.

Flo0807 avatar Jul 18 '24 08:07 Flo0807

Hi @Flo0807,

thank you for reporting this and especially for including the single file script to reproduce!

LiveView assumes that calling redirect(socket, external: link) actually does a navigation and therefore blindly unloads the socket. This differs from the handling for links on the page, where we explicitly check if it's a special URL like mailto. I'm not sure yet if we really want to change this behavior, as there is a quite straightforward way to handle this without redirect:

Add a event handler to your JS:

window.addEventListener("phx:open_mail", (e) => {
  window.open(e.detail.link);
});

and then push an event instead of using redirect:

def handle_event("link", _params, socket) do
  {:noreply, push_event(socket, "open_mail", %{link: "mailto:[email protected]"})}
end

Let me know what you think :)

SteffenDE avatar Jul 18 '24 10:07 SteffenDE

Thanks @SteffenDE

This solves my problem, but I think the behavior should be changed, or the behavior should be addressed in the docs because mailto links are explicitly allowed in redirect/2, but cause an unexpected unload of the socket.

Flo0807 avatar Jul 19 '24 13:07 Flo0807