Declarative routing for React web applications
—
Hooks for accessing routing state and performing navigation operations, including location access, parameter extraction, and programmatic navigation.
Returns a function for programmatic navigation.
/**
* Hook that returns a function for programmatic navigation
* @returns Navigation function for changing routes
*/
function useNavigate(): NavigateFunction;
interface NavigateFunction {
/** Navigate to a specific location */
(to: To, options?: NavigateOptions): void;
/** Navigate relative to history (back/forward) */
(delta: number): void;
}
interface NavigateOptions {
/** Replace current entry instead of pushing new entry */
replace?: boolean;
/** State object to pass with navigation */
state?: any;
/** Enable relative path resolution */
relative?: RelativeRoutingType;
/** Prevent scroll reset on navigation */
preventScrollReset?: boolean;
/** Flash the element after navigation */
unstable_flushSync?: boolean;
/** View transition name for page transitions */
unstable_viewTransition?: boolean;
}
type To = string | Partial<Path>;
type RelativeRoutingType = "route" | "path";Usage Examples:
import { useNavigate } from "react-router-dom";
function MyComponent() {
const navigate = useNavigate();
const handleSubmit = async (formData) => {
await saveData(formData);
// Navigate to success page
navigate("/success");
};
const goBack = () => {
// Go back one entry in history
navigate(-1);
};
const redirectWithState = () => {
navigate("/profile", {
state: { from: "settings" },
replace: true
});
};
return (
<div>
<button onClick={handleSubmit}>Save</button>
<button onClick={goBack}>Back</button>
<button onClick={redirectWithState}>Go to Profile</button>
</div>
);
}Returns the current location object representing the current URL.
/**
* Hook that returns the current location object
* @returns Current location with pathname, search, hash, and state
*/
function useLocation(): Location;
interface Location {
/** URL pathname */
pathname: string;
/** URL search parameters as string */
search: string;
/** URL hash fragment */
hash: string;
/** State object passed with navigation */
state: unknown;
/** Unique key for this location */
key: string;
}Usage Examples:
import { useLocation } from "react-router-dom";
function LocationDisplay() {
const location = useLocation();
return (
<div>
<p>Current Path: {location.pathname}</p>
<p>Search: {location.search}</p>
<p>Hash: {location.hash}</p>
<p>State: {JSON.stringify(location.state)}</p>
</div>
);
}
// Conditional rendering based on location
function Navigation() {
const location = useLocation();
const isHomePage = location.pathname === "/";
return (
<nav className={isHomePage ? "home-nav" : "page-nav"}>
{/* Navigation content */}
</nav>
);
}Returns parameters from the current route as key-value pairs.
/**
* Hook that returns route parameters from the current URL
* @returns Object containing route parameters
*/
function useParams<K extends string = string>(): Readonly<Params<K>>;
interface Params<K extends string = string> {
readonly [key in K]: string | undefined;
}Usage Examples:
import { useParams } from "react-router-dom";
// Route: /users/:userId/posts/:postId
function UserPost() {
const { userId, postId } = useParams();
// TypeScript users can specify parameter types
const params = useParams<"userId" | "postId">();
return (
<div>
<h1>User {userId}</h1>
<h2>Post {postId}</h2>
</div>
);
}
// Optional parameters
// Route: /products/:category/:productId?
function Product() {
const { category, productId } = useParams();
if (!productId) {
return <CategoryView category={category} />;
}
return <ProductView category={category} productId={productId} />;
}Provides access to URL search parameters with setter function.
/**
* Hook for reading and updating URL search parameters
* @param defaultInit - Default search parameters
* @returns Tuple of current search params and setter function
*/
function useSearchParams(
defaultInit?: URLSearchParamsInit
): [URLSearchParams, SetURLSearchParams];
type SetURLSearchParams = (
nextInit: URLSearchParamsInit | ((prev: URLSearchParams) => URLSearchParamsInit),
navigateOptions?: NavigateOptions
) => void;
type URLSearchParamsInit =
| string
| string[][]
| Record<string, string | string[]>
| URLSearchParams;Usage Examples:
import { useSearchParams } from "react-router-dom";
function SearchPage() {
const [searchParams, setSearchParams] = useSearchParams();
const query = searchParams.get("q") || "";
const category = searchParams.get("category") || "all";
const updateQuery = (newQuery: string) => {
setSearchParams(prev => {
prev.set("q", newQuery);
return prev;
});
};
const updateCategory = (newCategory: string) => {
setSearchParams({
q: query,
category: newCategory
});
};
return (
<div>
<input
value={query}
onChange={e => updateQuery(e.target.value)}
placeholder="Search..."
/>
<select
value={category}
onChange={e => updateCategory(e.target.value)}
>
<option value="all">All Categories</option>
<option value="books">Books</option>
<option value="electronics">Electronics</option>
</select>
</div>
);
}Generates href string for a given destination.
/**
* Hook that returns an href string for a given destination
* @param to - Navigation destination
* @param options - Href generation options
* @returns Href string for the destination
*/
function useHref(to: To, options?: { relative?: RelativeRoutingType }): string;Usage Examples:
import { useHref } from "react-router-dom";
function CustomLink({ to, children, ...props }) {
const href = useHref(to);
return (
<a href={href} {...props}>
{children}
</a>
);
}
// Generate href for external use
function ShareButton() {
const currentHref = useHref(".", { relative: "path" });
const fullUrl = `${window.location.origin}${currentHref}`;
const share = () => {
navigator.share({ url: fullUrl });
};
return <button onClick={share}>Share</button>;
}Resolves a path against the current location.
/**
* Hook that resolves a relative path against the current location
* @param to - Path to resolve
* @param options - Path resolution options
* @returns Resolved path object
*/
function useResolvedPath(
to: To,
options?: { relative?: RelativeRoutingType }
): Path;
interface Path {
pathname: string;
search: string;
hash: string;
}Usage Example:
import { useResolvedPath, useMatch } from "react-router-dom";
function CustomNavLink({ to, children, ...props }) {
const resolved = useResolvedPath(to);
const match = useMatch({ path: resolved.pathname, end: true });
return (
<a
href={resolved.pathname + resolved.search + resolved.hash}
className={match ? "active" : ""}
{...props}
>
{children}
</a>
);
}Returns match information for a given path pattern.
/**
* Hook that returns match information for a path pattern
* @param pattern - Path pattern to match against
* @returns Match object or null if no match
*/
function useMatch<T extends Record<string, any>>(
pattern: PathPattern<T> | string
): PathMatch<T> | null;
interface PathPattern<T extends Record<string, any> = Record<string, any>> {
path: string;
caseSensitive?: boolean;
end?: boolean;
}
interface PathMatch<T extends Record<string, any> = Record<string, any>> {
params: T;
pathname: string;
pathnameBase: string;
pattern: PathPattern<T>;
}Usage Example:
import { useMatch } from "react-router-dom";
function UserProfileTab() {
const match = useMatch("/users/:userId/profile");
if (match) {
return (
<div>
Currently viewing profile for user {match.params.userId}
</div>
);
}
return null;
}Returns an array of current route matches.
/**
* Hook that returns the current route match hierarchy
* @returns Array of route matches from root to current
*/
function useMatches(): UIMatch[];
interface UIMatch<Data = unknown, Handle = unknown> {
/** Route ID */
id: string;
/** Matched pathname */
pathname: string;
/** Route parameters */
params: Params;
/** Route loader data */
data: Data;
/** Route handle data */
handle: Handle;
}Usage Example:
import { useMatches } from "react-router-dom";
function Breadcrumbs() {
const matches = useMatches();
const crumbs = matches
.filter(match => match.handle?.crumb)
.map(match => match.handle.crumb(match));
return (
<nav>
{crumbs.map((crumb, index) => (
<span key={index}>
{crumb}
{index < crumbs.length - 1 && " > "}
</span>
))}
</nav>
);
}Hook for accessing route errors in error boundary components.
/**
* Hook that returns the error thrown during route loading or rendering
* @returns Error object thrown in current route context
*/
function useRouteError(): unknown;Usage Examples:
import { useRouteError, isRouteErrorResponse } from "react-router-dom";
function ErrorBoundary() {
const error = useRouteError();
if (isRouteErrorResponse(error)) {
return (
<div>
<h1>Error {error.status}</h1>
<p>{error.statusText}</p>
{error.data && <p>{error.data}</p>}
</div>
);
}
return (
<div>
<h1>Something went wrong</h1>
<p>{error instanceof Error ? error.message : "Unknown error"}</p>
</div>
);
}
// Usage in route configuration
const routes = [
{
path: "/users/:id",
element: <User />,
errorElement: <ErrorBoundary />,
loader: async ({ params }) => {
const response = await fetch(`/api/users/${params.id}`);
if (!response.ok) {
throw new Response("User not found", { status: 404 });
}
return response.json();
},
},
];Hook that returns the current route outlet element.
/**
* Hook that returns the outlet element for current route
* @param context - Optional context to pass to child routes
* @returns JSX element for route outlet or null
*/
function useOutlet(context?: unknown): React.ReactElement | null;Usage Examples:
import { useOutlet } from "react-router-dom";
function Layout() {
const outlet = useOutlet();
return (
<div className="layout">
<header>My App</header>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<main>
{outlet || <div>No route matched</div>}
</main>
</div>
);
}
// With context
function LayoutWithContext() {
const outlet = useOutlet({ theme: "dark", user: currentUser });
return (
<div className="layout">
{outlet}
</div>
);
}
// Child route accessing context
function ChildRoute() {
const context = useOutletContext<{ theme: string; user: User }>();
return (
<div className={`theme-${context.theme}`}>
Welcome, {context.user.name}!
</div>
);
}Additional hooks for navigation state management.
/**
* Hook that returns navigation type for current location
* @returns Navigation type (POP, PUSH, or REPLACE)
*/
function useNavigationType(): NavigationType;
/**
* Hook that checks if component is inside a router context
* @returns True if inside router, false otherwise
*/
function useInRouterContext(): boolean;
type NavigationType = "POP" | "PUSH" | "REPLACE";Usage Examples:
import { useNavigationType, useInRouterContext } from "react-router-dom";
function NavigationInfo() {
const navigationType = useNavigationType();
const inRouter = useInRouterContext();
if (!inRouter) {
return <div>Not in router context</div>;
}
return (
<div>
Last navigation was: {navigationType}
{navigationType === "POP" && " (back/forward button)"}
{navigationType === "PUSH" && " (new entry)"}
{navigationType === "REPLACE" && " (replaced entry)"}
</div>
);
}Install with Tessl CLI
npx tessl i tessl/npm-react-router-dom