React Router search params are the values after the question mark in a URL, like ?q=react. The useSearchParams hook reads and updates them, which makes filters and tabs shareable through the address bar. Unlike route params in the path, search params are optional and unordered.
Read a search param
Call useSearchParams to get a URLSearchParams instance and a setter function. Use the get method on that instance to read a single value.
import { useSearchParams } from "react-router";
export default function Search() {
const [searchParams] = useSearchParams();
const query = searchParams.get("q");
return <p>Results for {query}</p>;
}For the URL /search?q=router, query is the string "router". A missing param returns null, so give the page a fallback value instead of rendering a blank label.
You can also pass a default value to useSearchParams, which applies when the URL has no search string.
Read several params at once
A filter page usually reads more than one value. Call get for each param you care about, with a fallback for the ones that can be missing.
import { useSearchParams } from "react-router";
export default function Products() {
const [searchParams] = useSearchParams();
const category = searchParams.get("category") || "all";
const sort = searchParams.get("sort") || "new";
return <p>Showing {category}, sorted by {sort}</p>;
}The fallbacks keep the page meaningful on a plain /products URL with no query string.
On /products?category=books&sort=old, the component shows both values.
Update search params
The setter accepts a string, an object, an array, or a function. Calling it navigates to a new URL with the updated query string.
function TabLinks() {
const [, setSearchParams] = useSearchParams();
return (
<nav>
<button onClick={() => setSearchParams({ tab: "one" })}>One</button>
<button onClick={() => setSearchParams({ tab: "two" })}>Two</button>
</nav>
);
}Clicking Two changes the URL to end in ?tab=two. The object form replaces the query string with the keys you pass.
A raw string works too, so passing ?tab=two produces the same URL.
To change one key while keeping the rest, use the function form and mutate the current URLSearchParams.
setSearchParams((searchParams) => {
searchParams.set("tab", "two");
return searchParams;
});This keeps any other params like ?q intact while switching the tab. The function form does not queue like React state, so call it once per change.
Why search params beat component state
Filters and tabs often live in component state, but the URL has three advantages:
- A copied link carries the filter with it.
- The back button moves through filter changes as history entries.
- A reload restores the exact view the user was on.
Loaders can also read search params from the request, which React Router loaders and actions explained covers. For required values, route params in the path fit better, covered in dynamic routes and URL parameters.
Keep sensitive values out of the query string, because the URL is logged and shared.
Common mistakes
- Reading a missing param without a fallback.
- Assuming setSearchParams merges when it actually replaces.
- Calling the function setter twice expecting queued updates.
- Treating search params as the source of truth for data that should come from a loader.
Rune AI
Key Insights
- Read a value with searchParams.get from useSearchParams.
- Update the URL by calling setSearchParams with a string or object.
- Use the function form to change one key without dropping the rest.
- Search params keep filters and tabs shareable through the URL.
Frequently Asked Questions
What is the difference between params and search params?
Does setSearchParams merge with existing params?
Can I read search params in a loader?
Conclusion
Search params hold the values after the ? in a URL. Read them with useSearchParams and update them with setSearchParams, which navigates to a new URL. Use the function form to change one key while keeping the rest.
More in this topic
How to Build a Dropdown Menu in React
Build a React dropdown menu with the ARIA menu button pattern. Handle open and close, keyboard arrows, and clicks outside the menu.
How to Animate React Components with Motion
Animate React components with the Motion library. Set up motion, add enter, hover, and exit animations, and respect reduced motion.
Headless UI Components Explained: Logic Without Locked Styling
Understand headless UI components and how libraries like Radix give you unstyled, accessible behavior that you style yourself.