GioJSdocs
On this page

navigate

Soft-navigate to a URL from any client code - outside components, where useRouter() is not available.

ts
import { navigate } from '@gio.js/react';

await navigate('/login', { replace: true });

Reference

ParameterTypeDefaultDescription
href (required)string-Where to go: a path, a query (?page=2), a hash, or an absolute URL. Build typed paths with href().
options.replacebooleanfalseReplace the current history entry instead of adding one.
options.scrollbooleantrueScroll to the top of the new page, or to the element its #hash names. false keeps the scroll position.
options.transition'fade' | 'slide-left' | 'slide-up' | 'scale' | falsefalseA view transition preset for the swap, where the browser supports document.startViewTransition.

Returns

A Promise<void> that resolves once the new page is on screen (or, for a full page load, once the browser has been told to load it).

Behavior

  • Same origin: the page is fetched (or taken from a fresh prefetch), its stylesheets loaded, and it is rendered into the running React root - shared layouts keep their state. History is updated, then the page scrolls and focus moves to the new <main>, with the title announced to screen readers.
  • Only a hash changes on the current page: no fetch, just a history entry and a scroll.
  • Full page loads instead: another origin, an answer that is not a GioJS page (JSON, a static host's 404.html, a server error page), a redirect that lands on another origin, or a network error.
  • A new deployment (the server answers 409 with x-gio-action: hard-reload) loads the target in full, so the tab picks up the new build - see deployment helpers.
  • After a redirect, history records the URL the redirect landed on, not href.
  • A later navigation supersedes an earlier one that has not finished; the earlier promise resolves without showing its page.
  • On the server it does nothing and resolves at once.

Errors

It rejects with a TypeError for an href that is not a valid URL, and for any scheme other than http: and https: - navigate('javascript:alert(1)') never runs script, so passing user input to it is not an XSS sink.

Examples

After a logout request

lib/session-client.ts
import { navigate } from '@gio.js/react';

export async function logout(): Promise<void> {
  await fetch('/api/logout', { method: 'POST' });
  await navigate('/', { replace: true });
}

From a WebSocket message

ts
socket.addEventListener('message', (event) => {
  const message = JSON.parse(event.data);
  if (message.type === 'game-started') void navigate(`/games/${message.id}`);
});

Inside components

In a component, prefer useRouter(): router.push(href) and router.replace(href) do the same as navigate, and the router adds back, forward, refresh and prefetch.

Good to know

  • Navigating to the URL already shown replaces its history entry, as a browser does for a link to the current page.
  • Fresh data after a mutation. Any same-origin fetch() with a method other than GET, HEAD or OPTIONS clears the prefetch cache, so a navigation after it never shows a page prefetched before the change.
  • Static export. Soft navigation works on any static host; pages that are not GioJS pages load in full.

Version history

VersionChanges
v0.1.0-beta.8Introduced, with the router hooks.