usePathname
Read the path of the current page - without query, hash or locale prefix - on the server and in the browser.
tsx
import { usePathname } from '@gio.js/react';
export function Breadcrumb() {
const pathname = usePathname(); // '/blog/hello-world'
return <p>You are at {pathname}</p>;
}Reference
Parameters
usePathname takes no parameters.
Returns
A string: the path the page was rendered for, starting with /.
| URL | usePathname() |
|---|---|
/ | '/' |
/blog/hello?tab=comments#top | '/blog/hello' |
/fr/about (with [i18n] locales en, fr) | '/about' |
/docs rewritten to /help by a [[rewrites]] rule | '/help' |
/blog/caf%C3%A9 | '/blog/caf%C3%A9' |
Behavior
- The value comes from the route the server matched. The server render and the hydration render read the same value, so there is never a hydration mismatch.
- After a soft navigation, every hydrated component reads the new page's path. After a redirect it is where the redirect landed.
- In a
not-found.tsxorerror.tsxpage it is the path that was requested. - Outside a tree GioJS rendered (a component rendered by a unit test or in a separate React root) it falls back to
window.location.pathname, and'/'on the server.
Examples
Marking the active link
app/(site)/nav.tsx
import { GioLink, usePathname } from '@gio.js/react';
export function Nav() {
const pathname = usePathname();
const link = (href: string, label: string) => (
<GioLink href={href} aria-current={pathname === href ? 'page' : undefined}>
{label}
</GioLink>
);
return (
<nav>
{link('/', 'Home')}
{link('/pricing', 'Pricing')}
</nav>
);
}Tracking page views
The effect runs on the first render in the browser and again after every navigation to another path. sendBeacon rather than a POST fetch(): the router treats every same-origin fetch() mutation as a change and empties its prefetch cache.
app/(site)/analytics.tsx
import { useEffect } from 'react';
import { usePathname } from '@gio.js/react';
export function Analytics() {
const pathname = usePathname();
useEffect(() => {
navigator.sendBeacon('/api/page-view', JSON.stringify({ path: pathname }));
}, [pathname]);
return null;
}Code outside React can listen for the gio:navigated event on window instead, which the router dispatches each time it renders a page in place (links, back and forward, form answers).
Good to know
- In the root layout it never updates.
app/layout.tsxis server-only HTML that a soft navigation does not re-render, so there the value stays that of the page loaded in full. Read it in a route group's layout or a page. - Escapes in the path are kept as the server canonicalized it: unreserved characters are decoded, everything else stays percent-encoded (
%20,%C3%A9). Decode withdecodeURIComponentbefore showing it. - A trailing slash in the URL is kept (
/blog/), although the router ignores it when it matches the route. - With
[i18n], combine it withuseLocale()to rebuild the prefixed URL. - A
route.tshandler has no hook: readreq.path.
Related
- Linking & Navigating - the router hooks together.
useParams,useSearchParams- the rest of the URL.useRouter- navigate from code.<GioLink>- links that navigate on the client.
Version history
| Version | Changes |
|---|---|
v0.1.0-beta.8 | Introduced. |