phoenixframework / phoenix_live_view

Rich, real-time user experiences with server-rendered HTML
https://hex.pm/packages/phoenix_live_view
MIT License
6.23k stars 932 forks source link

mailto link in redirect causes live view to disconnect #3352

Open Flo0807 opened 4 months ago

Flo0807 commented 4 months ago

Environment

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:info@example.com")}
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.

SteffenDE commented 4 months ago

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:info@example.com"})}
end

Let me know what you think :)

Flo0807 commented 4 months ago

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.