mailto link in redirect causes live view to disconnect
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.
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 :)
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.