Design Converter
Education
Last updated on May 13, 2024
Last updated on May 13, 2024
Senior Software Engineer
Software Development Executive - I
A frontend innovator with 3+ years of crafting dynamic React experiences. Passionate about intuitive UI, performance optimization, and solving complex problems with elegant code. Probably refining micro-interactions while brainstorming the future of the web.
Query parameters are an essential part of the web. They are used to pass state information between client components and server components. Whether you're building a dashboard with filters or a search page that retains user input across navigations, query parameters are the key to preserving and transmitting this data.
Query parameters, also known as URL parameters or search parameters, are a set of key-value pairs appended to the URL string. They start after the question mark (?) and are separated by the ampersand (&) when there are multiple parameters. Each key-value pair is a query parameter that allows you to pass data to the server components or manipulate the content on the client side without the need for a page reload.
In the context of a URL, query parameters are used to sort, filter, or search data on a page. They are a part of the URL string that comes after the pathname and can be used to pass additional information to the page components. This is particularly useful when you need to retrieve or display data based on user input or when you want to create dynamic routes that respond to changes in the query string.
Let's look at an example of a URL with query parameters:
1https://www.example.com/products?category=shoes&color=black
In this URL, category and color are the keys, while shoes and black are their respective values. These query parameters can be used by server components to fetch data that matches the specified category and color, or by client components to highlight the active filters on the current page.
Here's a simple code snippet showing how you might access these parameters within a Next.js page component:
1import { useRouter } from 'next/router'; 2 3const ProductsPage = () => { 4 const router = useRouter(); 5 const { category, color } = router.query; 6 7 console.log('Selected category:', category); 8 console.log('Selected color:', color); 9 10 // Fetch data based on query parameters 11 // ... 12 13 return ( 14 <div> 15 <h2>Filtered Products</h2> 16 {/* Render products based on the query parameters */} 17 </div> 18 ); 19};
In this example, we use the useRouter hook from Next.js to access the router object, which contains the query object. The query object holds the query parameters from the current URL, allowing us to log their values and potentially use them to fetch data or render specific components on the page.
Next.js offers a file-system-based routing mechanism, where files and folders in the pages directory automatically become routes in your application. This approach simplifies the creation of new pages and dynamic routes. When it comes to handling query parameters, Next.js provides built-in hooks and functions that make accessing these parameters straightforward, whether you're on the client side or the server side.
The useRouter hook is part of the Next.js router and is a client-side hook that allows you to access the router object within your page components. This router object contains the query object, which holds the query parameters of the current URL.
Here's a code snippet demonstrating how to use the useRouter hook to access query parameters:
1import { useRouter } from 'next/router'; 2 3const MyPage = () => { 4 const router = useRouter(); 5 const { query } = router; 6 7 console.log('Query parameters:', query); 8 9 return ( 10 <div> 11 <h2>Accessing Query Parameters</h2> 12 {/* Render content based on query parameters */} 13 </div> 14 ); 15}; 16 17export default MyPage;
In this example, we import the useRouter hook from the Next.js router library and use it to retrieve the router object. We then destructure the query object from router to access the query parameters.
When you need to fetch data based on query parameters during server-side rendering, you can use the getServerSideProps function. This function runs on the server for each request and receives the context object, which includes the query object.
Here's how you can access query parameters in getServerSideProps:
1export async function getServerSideProps(context) { 2 const { query } = context; 3 4 console.log('Server-side query parameters:', query); 5 6 // Fetch data based on query parameters 7 // ... 8 9 return { 10 props: {}, // Pass data to the page as props 11 }; 12}
In this code snippet, getServerSideProps is an async function that receives the context parameter. The query object is extracted from context, allowing you to log the query parameters and fetch data accordingly.
For static generation, Next.js provides getStaticProps and getStaticPaths. While getStaticProps is used to fetch data at build time, getStaticPaths is used to specify dynamic routes that should be pre-rendered.
Here's an example of accessing query parameters with getStaticPaths:
1export async function getStaticPaths() { 2 // Define paths with query parameters that should be statically generated 3 return { 4 paths: [ 5 { params: { category: 'shoes' } }, 6 { params: { category: 'accessories' } }, 7 // More paths... 8 ], 9 fallback: false, 10 }; 11} 12 13export async function getStaticProps({ params }) { 14 console.log('Static generation query parameters:', params); 15 16 // Fetch data based on query parameters 17 // ... 18 19 return { 20 props: {}, // Pass data to the page as props 21 }; 22}
In getStaticPaths, we define the paths that include the query parameters we want to pre-render. In getStaticProps, we access these parameters through the params object provided by the context.
Dynamic routes in Next.js allow you to create pages that can match a variety of URL structures. These routes are defined by placing square brackets around a file or folder name within the ‘pages' directory. For example, a file named [id].js would match any route like /posts/1 or /posts/abc. This flexibility is particularly useful when you want to create pages that adapt to different content based on the URL parameters provided.
To create a dynamic page that responds to query parameters, you first define the dynamic route using the file naming convention mentioned above. Then, within the page component, you can access the dynamic segments of the URL as query parameters using the useRouter hook or the context object provided to getServerSideProps or getStaticProps.
Here's an example of how to create a dynamic route that responds to query parameters:
Create a file in the ‘pages’ directory that corresponds to the dynamic segment of the URL, for example, [category].js.
Within this file, use the useRouter hook to access the dynamic segment and any additional query parameters.
1// pages/[category].js 2import { useRouter } from 'next/router'; 3 4const CategoryPage = () => { 5 const router = useRouter(); 6 const { category } = router.query; // Access the dynamic segment 7 const { filter } = router.query; // Access an additional query parameter 8 9 console.log('Category:', category); 10 console.log('Filter:', filter); 11 12 // Fetch data based on the category and filter query parameters 13 // ... 14 15 return ( 16 <div> 17 <h2>Products in {category}</h2> 18 {/* Render products based on the category and filter */} 19 </div> 20 ); 21}; 22 23export default CategoryPage;
In this example, the file [category].js will match routes like /shoes or /accessories, and the dynamic segment will be available as a query parameter under the key category. If the URL includes additional query parameters, such as /shoes?filter=on-sale, the filter parameter can also be accessed from the query object.
Let's consider a more concrete example. Suppose you have an e-commerce application where you want to display products based on their category and optional filters like price range or brand. You could create a dynamic route to handle this:
Create a file named [category].js in the ‘pages’ directory.
Use the useRouter hook to access the category and any additional query parameters.
1// pages/[category].js 2import { useRouter } from 'next/router'; 3 4const ProductsByCategory = () => { 5 const router = useRouter(); 6 const { category, price, brand } = router.query; 7 8 console.log(`Displaying products in category: ${category} with price: ${price} and brand: ${brand}`); 9 10 // Fetch and display products based on the category, price, and brand 11 // ... 12 13 return ( 14 <div> 15 <h2>Products in {category}</h2> 16 {/* Render products based on the category and additional filters */} 17 </div> 18 ); 19}; 20 21export default ProductsByCategory;
With this setup, a URL like /shoes?price=under-100&brand=nike would render the ProductsByCategory component, and within that component, you could fetch and display products that are shoes under $100 from Nike.
In Next.js, you can programmatically navigate between pages and manipulate query parameters using the Next router methods router.push and router.replace. These methods allow you to update the URL and navigate to a new page without a full page refresh, providing a smoother user experience.
The router.push method is used to navigate to a new page and add a new entry to the browser's history stack. This means that when the user clicks the back button, they will return to the previous page.
Here's a code snippet demonstrating how to use router.push to navigate with query parameters:
1import { useRouter } from 'next/router'; 2 3const MyComponent = () => { 4 const router = useRouter(); 5 6 const handleSearch = (searchTerm) => { 7 // Navigate to the same page with a new query parameter for the search term 8 router.push({ 9 pathname: router.pathname, 10 query: { ...router.query, search: searchTerm }, 11 }); 12 }; 13 14 return ( 15 <div> 16 <input type="text" placeholder="Search..." onChange={(e) => handleSearch(e.target.value)} /> 17 {/* Other content */} 18 </div> 19 ); 20}; 21 22export default MyComponent;
In this example, when the user types into the search input, the handleSearch function is called, which uses router.push to update the current URL with the new search term while preserving other existing query parameters.
The router.replace method is similar to router.push, but it replaces the current entry in the history stack instead of adding a new one. This is useful when you want to navigate to a new page but don't want the user to be able to go back to the previous state.
Here's how you can use router.replace:
1import { useRouter } from 'next/router'; 2 3const MyComponent = () => { 4 const router = useRouter(); 5 6 const handleFilterChange = (filter) => { 7 // Replace the current URL with a new query parameter for the filter 8 router.replace({ 9 pathname: router.pathname, 10 query: { ...router.query, filter }, 11 }); 12 }; 13 14 return ( 15 <div> 16 <select onChange={(e) => handleFilterChange(e.target.value)}> 17 <option value="all">All</option> 18 <option value="available">Available</option> 19 <option value="sold-out">Sold Out</option> 20 </select> 21 {/* Other content */} 22 </div> 23 ); 24}; 25 26export default MyComponent;
In this example, when the user selects a filter option, the handleFilterChange function updates the URL with the selected filter without adding a new history entry.
When navigating between pages, you may want to preserve certain query parameters to maintain the application's state across page transitions. There are several strategies to achieve this:
Passing Query Parameters Manually: When using router.push or router.replace, you can manually include the query parameters you want to preserve in the new URL.
Using a Global State Management Library: Libraries like Redux or Zustand can help manage the application state globally, including the state represented by query parameters.
Storing in Local Storage or Session Storage: For more persistent state management across page reloads, you can store query parameters in local storage or session storage and retrieve them when needed.
Custom Hooks: Creating custom hooks to manage query parameters can abstract the logic of preserving parameters during navigation, making your components cleaner and more reusable.
In conclusion, query parameters are a fundamental feature in Next.js that enable dynamic and stateful web applications. We've covered how to access, manipulate, and maintain query parameters, ensuring seamless navigation and data retrieval. With the useRouter hook, dynamic routing, and methods like router.push and router.replace, you have the tools to craft interactive user experiences. Keep these insights in mind as you develop with Next.js, and you'll be well on your way to creating more engaging and personalized web applications.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.