DEV Community

Will Ceolin
Will Ceolin

Posted on

Phoenix LiveView: When to use navigate, patch, href, redirect, push_patch, push_navigate

TL;DR

  • navigate and push_navigate: When you're navigating to the same live_session.
  • patch and push_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 and redirect: When you're navigating to another live session or outside a live view.
  • Don't use navigate when navigating to another live_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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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)