Socket connection occurs on open redirect link in LiveView page

When I click a link that redirects to other page in LiveView page,
socket connection occurs again.

For example,

Codes

defmodule MyApp.TestLive do
  use MyAppWeb, :live_view

  def mount(_params, _session, socket) do
    "mounted" |> IO.inspect()
    {:ok, socket}
  end

  def render(assigns) do
    ~L"""
      <a href="<%= Routes.test_path(@socket, :test0) %>">link</a>
    """
  end
end

defmodule MyApp.TestController do
  use MyAppWeb, :controller

  def test0(conn, _params) do
    conn
    |> redirect(to: Routes.test_path(conn, :test1))
  end

  def test1(conn, _params) do
    conn
    |> html("""
    <html>
      <body>Test</body>
    </html>
    """)
  end
end

Logs

14:58:38.266 request_id=FporBZekJIh2BK0AABek [info] GET /test0
14:58:38.285 request_id=FporBZekJIh2BK0AABek [info] Sent 302 in 18ms
14:58:38.337 request_id=FporBZvfUYC-ba4AACdh [info] GET /test1
14:58:38.338 [info] CONNECTED TO Phoenix.LiveView.Socket in 174µs <<<- problem
  Transport: :websocket
  Serializer: Phoenix.Socket.V2.JSONSerializer
  Parameters: %{...}
"mounted" <<<- live view is mounted again
14:58:38.357 request_id=FporBZvfUYC-ba4AACdh [info] Sent 200 in 19ms

Developer Tool

Maybe onclose tries to reconnect the socket.

How to prevent this?

The link in your TestLive example is pointing to a “plain” Phoenix controller path, not another LiveView, which is then redirecting to a second controller path.

If you want the socket to remain open you must use live_redirect/2 in the HTML, pointing to a path defined with live/4 in your router. On the server side, push_redirect/2 will redirect the user to a live/4 while keeping and reusing the existing connection.

Straight redirect/2 calls will instruct the browser to do a full page reload and therefore re-parse the scripts and renegotiate the socket connection.

Is this the actual code where you’re experiencing this problem, or a simplified example?

1 Like