Bird
Raised Fist0
NextJSframework~10 mins

URL state with searchParams in NextJS - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - URL state with searchParams
User opens page
↓
Parse URL searchParams
↓
Initialize component state from searchParams
↓
Render UI with state
↓
User interacts (e.g., changes filter)
↓
Update state
↓
Update URL searchParams
↓
Re-render UI with new state
The app reads URL searchParams to set initial state, then updates both state and URL when user interacts.
Execution Sample
NextJS
import { useSearchParams, useRouter } from 'next/navigation';
import { useState, useEffect } from 'react';

export default function Filter() {
  const searchParams = useSearchParams();
  const router = useRouter();
  const [filter, setFilter] = useState('');

  useEffect(() => {
    setFilter(searchParams.get('filter') || '');
  }, [searchParams]);

  function updateFilter(newFilter) {
    const params = new URLSearchParams(searchParams);
    if (newFilter) params.set('filter', newFilter);
    else params.delete('filter');
    router.replace(`?${params.toString()}`);
  }

  return <input value={filter} onChange={e => {
    setFilter(e.target.value);
    updateFilter(e.target.value);
  }} />;
}
This component reads 'filter' from URL, shows it in input, and updates URL when input changes.
Execution Table
StepActionsearchParams.get('filter')State filterURL after router.replaceRendered input value
1Page loads with URL '?filter=apple''apple''apple''?filter=apple''apple'
2User types 'banana' in input'apple''banana''?filter=banana''banana'
3User clears input (empty string)'banana''''' (no filter param)''
4User types 'cherry'null'cherry''?filter=cherry''cherry'
5User reloads page with '?filter=cherry''cherry''cherry''?filter=cherry''cherry'
6User types 'date''cherry''date''?filter=date''date'
7User deletes filter param manually from URLnull''''''
8User types 'eggfruit'null'eggfruit''?filter=eggfruit''eggfruit'
9ExitN/AN/AN/AN/A
💡 User stops interacting; URL and state stay synced.
Variable Tracker
VariableStartAfter 1After 2After 3After 4After 5After 6After 7After 8Final
searchParams.get('filter')null'apple''banana'null'cherry''cherry''date'null'eggfruit''eggfruit'
State filter'''apple''banana''''cherry''cherry''date''''eggfruit''eggfruit'
URL after router.replace'''?filter=apple''?filter=banana''''?filter=cherry''?filter=cherry''?filter=date''''?filter=eggfruit''?filter=eggfruit'
Key Moments - 3 Insights
Why does the input show the old filter value before typing?
At step 2 in execution_table, the input value updates only after the state changes, which happens after reading the old searchParams. The component uses the URL param as initial state, then updates state on input.
What happens if the user clears the input? Does the URL keep the filter param?
At step 3, when input is empty, the code deletes the 'filter' param from URL, so the URL no longer has it, and state filter becomes empty string.
How does the URL update without a full page reload?
The router.replace method updates the URL in the browser without reloading the page, keeping the app state and UI in sync.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 4. What is the URL after router.replace?
A'' (no filter param)
B'?filter=cherry'
C'?filter=banana'
D'?filter=apple'
💡 Hint
Check the 'URL after router.replace' column at step 4 in execution_table.
According to variable_tracker, what is the state filter after step 6?
A'cherry'
B''
C'date'
D'eggfruit'
💡 Hint
Look at the 'State filter' row and the 'After 6' column in variable_tracker.
If the user manually removes the filter param from the URL, what will the input show next?
A'' (empty string)
B'date'
C'apple'
D'eggfruit'
💡 Hint
See step 7 in execution_table and the 'State filter' value.
Concept Snapshot
URL state with searchParams in Next.js:
- Use useSearchParams() to read URL query params.
- Initialize component state from searchParams.
- On user input, update state and URL with router.replace.
- Removing a param deletes it from URL.
- URL and UI stay in sync without page reload.
Full Transcript
This example shows how a Next.js component uses the URL's searchParams to keep UI state in sync with the URL. When the page loads, it reads the 'filter' parameter from the URL and sets it as the input's value. When the user types in the input, the component updates its state and changes the URL's searchParams using router.replace, which updates the browser URL without reloading the page. Clearing the input removes the filter parameter from the URL. This keeps the UI and URL synchronized, allowing sharing or bookmarking of the current filter state.

Practice

(1/5)
1. What does the useSearchParams hook in Next.js App Router do?
easy
A. It fetches data from an API based on URL parameters.
B. It changes the URL path without reloading the page.
C. It reads and lets you access query parameters from the URL.
D. It manages local component state unrelated to the URL.

Solution

  1. Step 1: Understand the purpose of useSearchParams

    The hook is designed to read query parameters from the URL, making it easy to access values like ?page=2 or ?filter=active.
  2. Step 2: Compare with other options

    Changing URL path or fetching data are different tasks; useSearchParams specifically reads URL search parameters.
  3. Final Answer:

    It reads and lets you access query parameters from the URL. -> Option C
  4. Quick Check:

    useSearchParams reads URL query parameters = C [OK]
Hint: Remember: useSearchParams reads URL queries, not changes path [OK]
Common Mistakes:
  • Confusing useSearchParams with navigation or data fetching hooks
  • Thinking it changes the URL instead of reading it
  • Assuming it manages local state unrelated to URL
2. Which of the following is the correct way to import and use useSearchParams in a Next.js component?
easy
A. import { useSearchParams } from 'next/navigation'; const params = useParams();
B. import useSearchParams from 'next/router'; const params = useSearchParams();
C. import { useSearchParams } from 'next/router'; const params = useSearchParams();
D. import { useSearchParams } from 'next/navigation'; const params = useSearchParams();

Solution

  1. Step 1: Identify correct import source

    In Next.js App Router, useSearchParams is imported from 'next/navigation', not 'next/router'.
  2. Step 2: Check usage syntax

    The hook is called as useSearchParams(), returning the params object. Using useParams() is incorrect here.
  3. Final Answer:

    import { useSearchParams } from 'next/navigation'; const params = useSearchParams(); -> Option D
  4. Quick Check:

    Correct import and call = D [OK]
Hint: Import from 'next/navigation' and call useSearchParams() [OK]
Common Mistakes:
  • Importing from 'next/router' instead of 'next/navigation'
  • Calling useParams() instead of useSearchParams()
  • Using default import instead of named import
3. Given this Next.js component code snippet, what will be logged if the URL is ?page=3&sort=asc?
import { useSearchParams } from 'next/navigation';
export default function Page() {
  const searchParams = useSearchParams();
  console.log(searchParams.get('page'));
  console.log(searchParams.get('sort'));
  return null;
}
medium
A. 3 and asc
B. page and sort
C. null and null
D. undefined and undefined

Solution

  1. Step 1: Understand useSearchParams behavior

    useSearchParams returns an object with a .get() method to read query parameters by name.
  2. Step 2: Check the URL query parameters

    The URL has ?page=3 and ?sort=asc, so searchParams.get('page') returns '3' and searchParams.get('sort') returns 'asc'.
  3. Final Answer:

    3 and asc -> Option A
  4. Quick Check:

    searchParams.get('page') = '3', get('sort') = 'asc' [OK]
Hint: Use .get('key') to read exact query values [OK]
Common Mistakes:
  • Expecting keys instead of values
  • Confusing null with undefined for missing params
  • Not calling .get() method on searchParams
4. What is wrong with this Next.js component code that tries to read a search parameter?
import { useSearchParams } from 'next/navigation';
export default function Page() {
  const params = useSearchParams;
  const filter = params.get('filter');
  return <div>Filter: {filter}</div>;
}
medium
A. The import statement is incorrect; it should be from 'next/router'.
B. useSearchParams is not called as a function, so params is the function itself.
C. The component returns invalid JSX syntax with <div> tags.
D. The get method does not exist on the params object.

Solution

  1. Step 1: Check how useSearchParams is used

    The code assigns params = useSearchParams without parentheses, so params is the function itself, not the returned object.
  2. Step 2: Understand consequence of missing parentheses

    Calling params.get('filter') fails because params is a function, not the searchParams object with .get() method.
  3. Final Answer:

    useSearchParams is not called as a function, so params is the function itself. -> Option B
  4. Quick Check:

    Missing () after useSearchParams causes error = A [OK]
Hint: Always call useSearchParams() with parentheses [OK]
Common Mistakes:
  • Forgetting parentheses when calling hooks
  • Importing from wrong module
  • Misunderstanding JSX syntax for div
5. You want to build a Next.js page that shows a list filtered by a search term from the URL query parameter search. Which approach correctly updates the displayed list when the URL changes without a full page reload?
import { useSearchParams } from 'next/navigation';
import { useEffect, useState } from 'react';

export default function SearchPage() {
  const searchParams = useSearchParams();
  const [searchTerm, setSearchTerm] = useState('');

  // Which code below correctly updates searchTerm when URL changes?

  // A:
  // useEffect(() => {
  //   setSearchTerm(searchParams.get('search') || '');
  // }, [searchParams]);

  // B:
  // setSearchTerm(searchParams.get('search') || '');

  // C:
  // useEffect(() => {
  //   setSearchTerm(searchParams.search || '');
  // }, [searchParams]);

  // D:
  // useEffect(() => {
  //   setSearchTerm(searchParams.get('searchTerm') || '');
  // }, [searchParams]);

  return <div>Search: {searchTerm}</div>;
}
hard
A. Use useEffect with dependency on searchParams and call searchParams.get('search').
B. Call setSearchTerm directly without useEffect.
C. Use useEffect but access searchParams.search property (which does not exist).
D. Use useEffect but get 'searchTerm' key instead of 'search'.

Solution

  1. Step 1: Understand reactivity to URL changes

    useSearchParams returns a new object when URL changes, so useEffect with [searchParams] dependency runs on URL updates.
  2. Step 2: Correctly read the query parameter

    The parameter key is 'search', so use searchParams.get('search'). Accessing searchParams.search or wrong keys will fail.
  3. Final Answer:

    Use useEffect with dependency on searchParams and call searchParams.get('search'). -> Option A
  4. Quick Check:

    useEffect + searchParams.get('search') updates state on URL change = B [OK]
Hint: Use useEffect with searchParams dependency and .get('search') [OK]
Common Mistakes:
  • Calling setState outside useEffect causing infinite loops
  • Accessing non-existent properties on searchParams
  • Using wrong query parameter keys
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard