React Router Cheatsheet
Location and Search Params
Use this React Router reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
useLocation
import { useLocation } from "react-router"; const location = useLocation();
| Field | Example | Notes |
|---|---|---|
pathname | /concerts/paris | No search, no hash, includes basename |
search | ?page=2&sort=asc | Leading ? included, empty string if none |
hash | #lineup | Leading # included |
state | { from: "/checkout" } | Set by Link state or navigate |
key | "ab12cd" | Unique per history entry, "default" at start |
location.state lives in the history entry, not the URL. It survives back
and forward, it does not survive a hard reload or a shared link, and it is
never available on the server, so treat it as a hint and not as data.
Search Params in the Client
import { useSearchParams } from "react-router"; const [searchParams, setSearchParams] = useSearchParams(); const q = searchParams.get("q") ?? ""; const tags = searchParams.getAll("tag"); const page = Number(searchParams.get("page") ?? 1); // functional update, keeps the params you do not touch setSearchParams( (prev) => { prev.set("page", String(page + 1)); return prev; }, { replace: true, preventScrollReset: true } );
setSearchParams is a navigation. Without { replace: true } every
keystroke in a filter input pushes a history entry, and the back button
becomes useless.
URLSearchParams method | Use |
|---|---|
get(k) | First value or null |
getAll(k) | Every value, for checkbox groups |
has(k) | Presence check, has(k, v) checks a pair |
set(k, v) | Replace all values for k |
append(k, v) | Add another value for k |
delete(k) | Remove all values for k |
toString() | Serialize without the ? |
sort() | Stable ordering, handy for cache keys |
entries() | Iterate pairs |
Search Params on the Server
A loader gets the raw Request, so parse the URL there. This is the read
that matters in Framework mode, because it runs before render and can be
cached.
import type { Route } from "./+types/search"; export async function loader({ request }: Route.LoaderArgs) { const url = new URL(request.url); const q = url.searchParams.get("q") ?? ""; const page = Number(url.searchParams.get("page") ?? 1); return { results: await search(q, page), q, page }; }
v8 also passes a normalized url argument alongside request, stripped
of the router's own .data suffix and internal search params. Prefer it
when you only need the URL.
| Read search params with | When |
|---|---|
A loader plus new URL(request.url) | The value changes what you fetch |
useSearchParams | The value only changes what you render |
| Both | Server filters the list, client toggles a view mode |
Use a <Form method="get"> for a filter form and the params write
themselves from the input names, with no onChange handler at all.
Path Utilities
| Utility | Returns |
|---|---|
useHref(to) | The full href a Link would produce, basename included |
useResolvedPath(to) | A Path object for a relative to |
generatePath(pattern, params) | Fills :params into a pattern string |
matchPath(pattern, pathname) | A match with params, or null |
matchRoutes(routes, location) | The matched branch, for custom logic |
resolvePath(to, from) | Resolve one path against another |
href(path, params) | Framework mode, type safe from the route config |
import { generatePath, matchPath, href } from "react-router"; generatePath("/users/:id/posts/:postId", { id: "7", postId: "3" }); // "/users/7/posts/3" matchPath("/users/:id", "/users/7"); // { params: { id: "7" }, pathname: "/users/7", pattern: {...} } // href is checked against routes.ts, a typo is a type error <Link to={href("/products/:id", { id: "abc123" })}>Product</Link>
href percent encodes param values for a path segment and preserves the
slashes inside a splat value.
Hash Routing
Hash routing is a Declarative or Data mode setup for static hosts that
cannot rewrite every path to index.html.
import { HashRouter } from "react-router"; import { createHashRouter } from "react-router"; <HashRouter>{/* routes */}</HashRouter> const router = createHashRouter(routes);
Framework mode has no hash router. If you need a fully static deploy,
use ssr: false with prerender in react-router.config.ts and keep
real paths, which is better for crawlers anyway.