Search query parameters are a fundamental part of web applications, allowing us to pass data through URLs, filter content, maintain state, and enhance user experience. As a frontend developer working with Next.js, mastering query parameters is essential for building dynamic and interactive applications.
In this comprehensive guide, we'll explore how to work with search query parameters in Next.js, covering everything from basic usage to advanced patterns.
Query parameters appear in URLs after a question mark (?
) and are formatted as key-value pairs. Multiple parameters are separated by ampersands (&
).
For example, in the URL https://example.com/search?query=nextjs&page=2
, we have two query parameters:
query
with a value of nextjs
page
with a value of 2
These parameters provide a way to pass data to the page without requiring changes to the route structure.
If you're using the newer App Router introduced in Next.js 13, you have a few options:
'use client';
import {FC} from 'react';
import { useSearchParams } from 'next/navigation';
const SearchPage: FC =() => {
const searchParams = useSearchParams();
const query = searchParams.get('query');
const page = searchParams.get('page');
return (
<div>
<h1>Search Results</h1>
<p>Query: {query}</p>
<p>Page: {page}</p>
</div>
);
}
export const SearchPage;
Query parameters are always strings. If you need numeric or boolean values, you'll need to convert them:
const page = parseInt(searchParams.get('page') || '1', 10);
const showDetails = searchParams.get('details') === 'true';
With the App Router, we use the useRouter
and useSearchParams
hooks together:
'use client';
import {FC} from 'react';
import { useRouter, useSearchParams } from 'next/navigation';
const FilterComponent : FC = () => {
const router = useRouter();
const searchParams = useSearchParams();
const updateFilters = (newFilters) => {
// Create a new URLSearchParams object based on the current parameters
const params = new URLSearchParams(searchParams.toString());
// Update or add new parameters
Object.entries(newFilters).forEach(([key, value]) => {
params.set(key, value);
});
// Navigate to the new URL
router.push('?' + params.toString());
};
return (
<button onClick={() => updateFilters({ sort: 'price-asc', page: '1' })}>
Sort by Price
</button>
);
}
export default FilterComponent;
In client components, query parameters might not be available during the first render.
Solution: Use conditional rendering or default values:
function SearchResults() {
const searchParams = useSearchParams();
const query = searchParams.get('q');
if (!query) {
return <div>Enter a search term to see results</div>;
}
return <div>Results for: {query}</div>;
}
Query parameters are always strings.
Solution: Always convert to the appropriate type:
const page = parseInt(searchParams.get('page') || '1', 10);
const showDetails = searchParams.get('details') === 'true';
const selectedIds = searchParams.get('ids')?.split(',').map(Number) || [];
Setting query parameters can cause unnecessary re-renders.
Solution: Only update parameters when values actually change:
const updateSort = (newSort) => {
if (newSort !== searchParams.get('sort')) {
setParams({ sort: newSort });
}
};
Handling arrays in query parameters can be tricky.
Solution: Use comma-separated values or multiple parameters with the same name:
// Setting array parameters
const selectedFilters = ['red', 'blue', 'green'];
setParams({ colors: selectedFilters.join(',') });
// Reading array parameters
const colors = searchParams.get('colors')?.split(',') || [];
Query parameters are a powerful tool in Next.js for managing state, sharing links, and enhancing user experience. By understanding how to effectively get, set, and manage these parameters, you can build more dynamic and user-friendly applications.
Remember that the best approach may vary depending on your specific requirements and whether you're using the Pages Router or App Router. Always consider URL length limitations, parameter encoding, and type conversion when working with query parameters.
With the techniques covered in this guide, you should now be well-equipped to handle query parameters in your Next.js applications.