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
| Parameter | Type | Default | Description |
|---|---|---|---|
href (required) | string | - | Where to go: a path, a query (?page=2), a hash, or an absolute URL. Build typed paths with href(). |
options.replace | boolean | false | Replace the current history entry instead of adding one. |
options.scroll | boolean | true | Scroll 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' | false | false | A 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
409withx-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 thanGET,HEADorOPTIONSclears 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.
Related
Version history
| Version | Changes |
|---|---|
v0.1.0-beta.8 | Introduced, with the router hooks. |