Navigate API

primate/navigate exports browser navigation operations and their public TypeScript types.

import navigate from "primate/navigate";
import type {
  NavigateOptions,
  NavigationEventDetail,
  NavigationListener,
  NavigationSource,
} from "primate/navigate";

The runtime API is client-only. Import it from hydrated frontend or other browser code, not server rendering code. See the Client navigation guide for links, forms, partitions, and workflow examples.

function navigate(
  href: string,
  optionsOrEvent?: NavigateOptions | Event,
  event?: Event,
): Promise<void>;

Resolves href against the current page. Same-origin pathname or query changes fetch and apply a Primate page response, update history, and scroll to the destination hash. Cross-origin and non-page responses use location.assign() for normal document navigation.

The optional event may be passed as the second argument, or as the third when using options. Same-origin navigation calls preventDefault(); cross-origin navigation leaves a supplied event untouched. The promise resolves after the SPA operation completes, is superseded/fails, performs a shallow/hash update, or hands navigation to the browser. It does not return a success flag.

await navigate("/projects/42", { replace: true });

Named type export accepted by navigate().

type NavigateOptions = {
  replace?: boolean;
  shallow?: boolean;
  state?: unknown;
};

All members default to their absent/false behavior.

options.replace

replace?: boolean;

When true, replaces the current history entry instead of pushing a new one. It applies to full SPA, hash-only, and shallow same-origin navigation.

options.shallow

shallow?: boolean;

When true and the destination pathname matches the current pathname, updates the URL, entry state, and public request data without fetching, remounting, or scrolling. A different pathname performs normal navigation.

options.state

state?: unknown;

Ephemeral state associated with the destination history entry. Primate clones it with structuredClone; an unclonable value rejects navigate() before the current entry changes. State is retained only within the same client partition and document and is not exposed in public history.state.

refresh(): Promise<boolean>;

Fetches and applies fresh page data for the current pathname and query without changing URL/history or scrolling. Resolves true only when a successful Primate route response is applied and completion listeners run. It resolves false for failure, supersession, redirects/different requested locations, or non-page responses.

Refreshes coalesce while foreground navigation or another refresh is active. Foreground navigation supersedes a running refresh and schedules a trailing attempt; the interrupted attempt's promise resolves false.

after(listener: NavigationListener): () => void;

Registers a browser-global listener for successful view-changing Primate navigations. It runs after the destination view updates and receives the current absolute URL and cloned entry state. It does not run for failures, superseded/full-document, hash-only, or shallow navigation. Returns an unsubscribe function; repeated unsubscribe calls simply remove the same listener again.

Named type export used by navigate.after().

type NavigationListener = (
  detail: NavigationEventDetail,
) => void;

Listeners run synchronously from the primate:navigation-end browser event.

Named completion payload type.

type NavigationEventDetail = {
  source: NavigationSource;
  state: unknown;
  url: string;
};
type NavigationSource = "form" | "history" | "navigate" | "refresh";

Named type export. Enhanced forms report "form", Back/Forward reports "history", links and direct navigate() calls report "navigate", and successful refreshes report "refresh".

state(): unknown;

Returns a structured clone of the current entry's ephemeral state, or undefined when none exists or the entry belongs to another client partition. Mutating the returned value does not mutate stored entry state.

Error and fallback behavior

Invalid URLs and structuredClone failures reject navigate(). SPA transport, response, and rendering failures are logged with console.warn and resolve the navigation promise without changing history. A later navigation supersedes an earlier request; stale responses are discarded.

The entrypoint has no server-conditioned implementation. Calling these members during SSR accesses browser APIs and is unsupported.

Previous
I18N
Next
Events