usePathname
The usePathname hook provides access to the current pathname of the URL. It returns a string representing the current path without query parameters or hash fragments.
import { usePathname } from "@toapi/router";
function Navigation() { const pathname = usePathname();
return ( <nav> <a href="/" className={pathname === "/" ? "active" : ""}> Home </a> <a href="/about" className={pathname === "/about" ? "active" : ""}> About </a> </nav> );}Return Value
Section titled “Return Value”- Type:
string - Description: the current pathname without query parameters or hash fragment
- Examples:
/for the root path/usersfor a users page/users/123for a specific user/products/category/electronicsfor nested paths
Pathname Normalization
Section titled “Pathname Normalization”The pathname is normalized by the Router component:
- Trailing slashes are removed:
/users/becomes/users - Root path remains
/
Examples
Section titled “Examples”Active Navigation Links
Section titled “Active Navigation Links”import { Link, usePathname } from "@toapi/router";
function NavItem({ href, children }) { const pathname = usePathname(); const isActive = pathname === href;
return ( <Link href={href} className={`nav-item ${isActive ? "active" : ""}`}> {children} </Link> );}
function Navigation() { return ( <nav> <NavItem href="/">Home</NavItem> <NavItem href="/products">Products</NavItem> <NavItem href="/about">About</NavItem> <NavItem href="/contact">Contact</NavItem> </nav> );}Conditional Rendering Based on Path
Section titled “Conditional Rendering Based on Path”function Layout({ children }) { const pathname = usePathname(); const isAdminPage = pathname.startsWith("/admin"); const isPublicPage = ["/", "/about", "/contact"].includes(pathname);
return ( <div className="layout"> {!isAdminPage && <Header />}
<main className={isAdminPage ? "admin-layout" : "public-layout"}> {children} </main>
{isPublicPage && <Footer />} </div> );}Breadcrumb Generation
Section titled “Breadcrumb Generation”import { Link, usePathname } from "@toapi/router";
function Breadcrumbs() { const pathname = usePathname();
const pathSegments = pathname.split("/").filter(Boolean);
const breadcrumbs = pathSegments.map((segment, index) => { const href = "/" + pathSegments.slice(0, index + 1).join("/"); const label = segment.charAt(0).toUpperCase() + segment.slice(1); return { href, label }; });
return ( <nav aria-label="Breadcrumb"> <Link href="/">Home</Link> {breadcrumbs.map((crumb, index) => ( <span key={crumb.href}> <span> / </span> {index === breadcrumbs.length - 1 ? ( <span aria-current="page">{crumb.label}</span> ) : ( <Link href={crumb.href}>{crumb.label}</Link> )} </span> ))} </nav> );}Analytics and Tracking
Section titled “Analytics and Tracking”function AnalyticsProvider({ children }) { const pathname = usePathname();
useEffect(() => { analytics.track("Page View", { path: pathname, timestamp: new Date().toISOString(), }); }, [pathname]);
return <>{children}</>;}Best Practices
Section titled “Best Practices”- Use for UI state: perfect for conditional rendering and styling based on the current path.
- Memoize expensive computations: use
useMemofor complex path-based calculations. - Combine with other hooks: often used together with
useParamsanduseSearchParams. - Avoid side effects: don’t use pathname changes to trigger navigation — use
useRouterinstead.
Common Anti-Patterns
Section titled “Common Anti-Patterns”Don’t use it for navigation
Section titled “Don’t use it for navigation”// Wrong - don't navigate based on pathname changesuseEffect(() => { if (pathname === "/old-path") { router.push("/new-path"); }}, [pathname]);Don’t ignore normalization
Section titled “Don’t ignore normalization”// Wrong - might not match due to trailing slashconst isActive = pathname === "/users/";
// Correct - router normalizes trailing slashesconst isActive = pathname === "/users";Related
Section titled “Related”- useRouter — programmatic navigation
- useParams — access route parameters
- useSearchParams — access search parameters
- useHash — access the URL hash fragment