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.

LinkDemo.jsx
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.