TL;DR
-
navigate
andpush_navigate
: When you're navigating to the samelive_session
. -
patch
andpush_patch
: When you're navigating to the same module/page/liveview. For example, when only the attributes change - from/posts/1
to/posts/2
. -
href
andredirect
: When you're navigating to another live session or outside a live view. - Don't use
navigate
when navigating to anotherlive_session
.
Examples
Let's say we have the following routes:
live_session :public_routes do
live "/", HomeLive
live "/posts", PostsLive
end
live_session :private_routes do
live "/posts/:id/content, PostEdit, :content
live "/posts/:id/metadata, PostEdit, :metadata
end
We have two live sessions: public_routes
and private_routes
.
From / to /posts
In this case, we'll use navigate
(client) or push_navigate
(server) because we're navigating to the same public_routes
live session:
<.link navigate={~p"/posts"}>Posts</.link>
This will keep the browser page but mount a new LiveView process to reload its content only.
From /posts to /posts/:id/content
In this case, we'll use href
(client) or redirect
(server) because we're moving from the public_routes
live session to the private_routes
one:
<.link href={~p"/posts/#{post.id}/content"}>Edit</.link>
This will cause a full page reload.
From /posts/:id/content to /posts/:id/metadata
In this case, we'll use patch
(client) or push_patch
(server) because we're navigating to the same page/module. We're only changing the page attributes:
<.link patch={~p"/posts/:id/metadata"}>Metadata</.link>
When using patch
you'll also need to define a handle_params
callback to handle the parameters change.
While navigate
mounts a new live view, patch
updates the current live view, sending less data back.
Motivation
I recently made a mistake where the topbar would be displayed twice while navigating between different live sessions. This happens because I tried to:
live navigate (<.link navigate) across live sessions, which requires an extra round trip to the server and looks like the cause of your unwanted behavior. Regular link href is all you need here and it will not dispatch the loading event in that case, resolving the behavior you're seeing.
Reading the docs, it was confusing to me to understand the difference between all those options, especially because I was looking at the wrong places.
I was looking the push_navigate/2 and push_patch/2 docs but a better explanation is available on the live navigation and link attributes docs.
Top comments (0)