Navigation
Patch vs Navigate
What each navigation mode actually does to the socket
- Link
- handle_params
Key concepts
patch
and navigate
both keep the browser on the same
page without a full reload, but they do different things to the
LiveView process underneath: patch calls handle_params/3
on the LiveView that's already running; navigate mounts a brand new
one, in the same connection.
import React from "react";
import { Link } from "live_react";
export function LinkDemo({ currentPath, mountCount, paramsUpdateCount }) {
return (
<div className="flex flex-col gap-4">
<dl className="grid grid-cols-2 gap-x-4 gap-y-1 text-sm">
<dt className="text-muted-foreground">Current path</dt>
<dd>
<code>{currentPath}</code>
</dd>
<dt className="text-muted-foreground">Mount count</dt>
<dd>{mountCount}</dd>
<dt className="text-muted-foreground">Params update count</dt>
<dd>{paramsUpdateCount}</dd>
</dl>
<div className="flex gap-3">
{/* Same route, same query shape, different navigation mode — the
only thing that varies is patch vs navigate, so any difference
in the counts above is caused by that alone. */}
<Link patch="/examples/link-demo?visited=patch" className="rounded-md border px-3 py-1">
patch (same process, no remount)
</Link>
<Link
navigate="/examples/link-demo?visited=navigate"
className="rounded-md border px-3 py-1"
>
navigate (fresh mount, same process)
</Link>
</div>
</div>
);
}
How it works
mount_count is stored in the process dictionary, not in
an assign, specifically so it survives a remount — every route in
this app's router lives in the single default (unnamed) live
session, so navigate reuses the same BEAM process even
though it calls mount/3 again from scratch.
Click "patch": the URL changes, params_update_count
goes up, mount_count
does not — same process, same
mount, only handle_params/3
ran again. Click "navigate": mount_count
goes up too — a fresh LiveView, reusing the
connection but not the state.