We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Live Sessions in Phoenix LiveView: Reducing navigation time between LiveViews
Deankinyua
The main idea behind live sessions is to reduce navigation time when navigating a group of routes. Normally what happens when navigating between LiveViews is a HTTP request gets sent to the server, a connection is made and the new LiveView is mounted in place. However, this forces a full page reload making the user experience not so good.
With Live Sessions, that HTTP request doesn’t have to be sent as we can do a live_redirect over the existing web socket connection. If the LiveViews are not in the same live session a full page reload will be done instead.
Take the following as an example:
scope "/", ElixirDropsWeb do
pipe_through [:browser, :require_authenticated_user]
live_session :require_authenticated_user do
live "/profile", UserDropLive.Index, :index
live "/notifications", NotificationLive.Index, :index
live "/drops/:short_id/edit", UserDropLive.Index, :edit
live "/drops/new", UserDropLive.Index, :new
end
end
Let’s then say we have this link in the notification page:
<.link navigate={~p"/profile"}>
My drops
</.link>
Instead of our request flowing through the pipeline as a normal HTTP request would, it goes through the live session and that makes it much faster hence a better user experience. What if the profie page requires some kind of authentication to identify the current_user ?
That’s where on_mount hooks come into place. These are just functions that will either halt or continue the mounting process. For example, If the hook finds out that the person viewing the page is a guest, the :ensure_authenticated hook halts the connection from proceeding further.
live_session :require_authenticated_user,
on_mount: [
{ElixirDropsWeb.UserAuth, :ensure_authenticated},
{ElixirDropsWeb.UserAuth, :assign_current_user},
{ElixirDropsWeb.NavbarSearchHook, :navbar_search}
] do
live "/profile", UserDropLive.Index, :index
live "/notifications", NotificationLive.Index, :index
live "/drops/:short_id/edit", UserDropLive.Index, :edit
live "/drops/new", UserDropLive.Index, :new
end
It looks like this:
# the auth module
def on_mount(:ensure_authenticated, _params, session, socket) do
socket = assign_current_user(socket, session)
if socket.assigns.current_user do
{:cont, socket}
else
socket =
socket
|> Phoenix.LiveView.put_flash(:error, "You must log in to access this page.")
|> Phoenix.LiveView.redirect(to: ~p"/")
{:halt, socket}
end
end
copied to clipboard
Comments (0)
Sign in with GitHub to join the discussion