Next.js UserRouter provides a flexible and efficient way to handle routing and navigation in your application. This is made possible through the use of pages and links.
With UserRouter, you can define pages as functions that return JSX elements, allowing for dynamic and server-side rendering. Each page is associated with a unique URL, enabling seamless navigation between them.
The UserRouter API provides a range of methods for managing routing and navigation, including getInitialProps, getServerSideProps, and Link. These methods enable you to fetch data, handle redirects, and create links between pages.
In Next.js, pages are organized in a directory structure, with each page being a separate file. This allows for easy maintenance and updates of your application's routing configuration.
Next.js Routing Basics
The routeChangeStart event is triggered when a route is about to change, which means when a user clicks a link to navigate to a new page, an event is triggered.
You can subscribe to this event using the on method provided by the Next.js router, which takes a callback function as its second argument.
The routeChangeStart event is triggered by the Next.js router, not the browser, which means routing outside of the Next.js router won't trigger the event.
Here are the key events and methods for Next.js routing:
Shallow Routing
Shallow routing is a game-changer for Next.js developers. It allows us to make changes to the path of a page without running data-fetching methods again, retaining the state of the page even after changing the URL.
The router object will have access to the updated pathname, which is useful when changing the URL means adding a new query. This is demonstrated in the example where the URL is changed to /about with a new query, username.
We can specify if the routing is shallow or not by using the shallow property in the router.push method or the Link component. By default, both methods default to false.
The router.push method is an alternative to the Next.js Link component, and it's used for navigating between pages. In the example, we navigate to the current page, /about, but with a new query, username.
Shallow routing is particularly useful when we need to update the URL without triggering data-fetching methods. This can improve the performance of our application by reducing unnecessary data fetching.
The router object will not call getServerSideProps or any other data-fetching methods when using shallow routing. This is because the routing is shallow, and the data fetching is not triggered.
We can use the shallow property to specify if the routing is shallow or not. This property is used in both the router.push method and the Link component.
Next.js Pages and Routing
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, making it easier to handle complex navigation scenarios. You can create a file named [category].js in the ‘pages’ directory to handle dynamic routes with query parameters.
For example, 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.
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 are some key benefits of Next.js routing:
- File-system-based routing simplifies the creation of new pages and dynamic routes.
- Dynamic routes can handle query parameters, such as category and price range.
- Use the useRouter hook to access dynamic segments and query parameters.
- getServerSideProps and getStaticProps provide context objects for accessing query parameters.
Next.js Router Events
The router object in Next.js has several properties and methods, including the events property, which allows you to listen to router events. This is useful for creating a loading indicator between page navigations.
Some common use cases for Next.js router events include creating a loading indicator, custom monitoring of user navigation behavior, determining the load time of a page, and animations during navigations. These use cases can be particularly useful for server-side rendering in Next.js.
The routeChangeStart event is triggered when a route is about to change, and it can be used to display a loading indicator. This event is triggered by the Next.js router, not the browser.
You can subscribe to router events on any page or component using the on method, and unsubscribe using the off method. The routeChangeStart event returns the URL that the user is navigating to and an object with a shallow property that indicates whether the routing is shallow or not.
Here are some common router events in Next.js:
- routeChangeStart: triggered when a route is about to change
- routeChangeComplete: triggered when a route changes completely
- browerHistoryChangeStart: triggered when the browser history is about to change
- browerHistoryChangeComplete: triggered when the browser history changes completely
The routeChangeStart event is particularly useful for server-side rendering in Next.js, where data fetching can cause delays during routing. By using the routeChangeStart event, you can display a loading indicator and inform the user that the page is loading.
The usePathname hook in Next.js 14 can also be used to retrieve the current URL pathname or the current route, providing the path to the current page. This can be useful for designating the active link by highlighting the current route with a distinct color.
Retrieving and Manipulating Routes
You can retrieve the current route in Next.js using the usePathname hook from the next/navigation module, which was introduced in Next.js 14. This hook provides the path to the current page.
To subscribe to router events, you can use the on method, such as the routeChangeStart event, which is triggered when a route is about to change. This event is triggered by the Next.js router, not the browser, so routing outside of the Next.js router won't trigger the event.
The router object also provides methods for shallow routing, which helps retain the state of the page even after changing the URL. You can specify if the routing is shallow or not using the shallow property, which defaults to false.
Here are some ways to use the usePathname hook:
- Constructing breadcrumbs on mobile website versions
- Designating the active link by highlighting the current route
- Triggering animations and transitions while navigating between targeted routes
You can also use the useRouter hook to access the current route, but this is now deprecated in favor of usePathname in Next.js 14.
The router.push method is used to navigate to a new page and add a new entry to the browser's history stack, preserving existing query parameters. For example, you can use it to update the current URL with a new search term while preserving other existing query parameters.
Here are some key things to keep in mind when using the router.push method:
- It adds a new entry to the browser's history stack
- It preserves existing query parameters
- It is used to navigate to a new page
Dynamic Routing with Query Parameters
You can create dynamic routes in Next.js by using file naming conventions that include dynamic segments. For example, creating a file named [category].js in the 'pages' directory will match routes like /shoes or /accessories.
Dynamic routes can respond to query parameters, which can be accessed using the useRouter hook or the context object provided to getServerSideProps or getStaticProps.
To access dynamic segments of the URL as query parameters, you can use the useRouter hook within the page component. This hook allows you to access the dynamic segment and any additional query parameters.
Here are the steps to create a dynamic route that responds to query parameters:
1. Create a file in the ‘pages’ directory that corresponds to the dynamic segment of the URL, for example, [category].js.
2. Within this file, use the useRouter hook to access the dynamic segment and any additional query parameters.
For example, a URL like /shoes?filter=on-sale would render the ProductsByCategory component, and within that component, you could fetch and display products that are shoes under $100 from Nike.
You can also 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.
To preserve query parameters during navigation, you can use one of the following strategies:
1. 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.
2. 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.
3. 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.
4. 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.
Preserving and Handling Query Parameters
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.
To preserve certain query parameters during navigation, you can pass them manually when using router.push or router.replace. This involves including the query parameters you want to preserve in the new URL.
You can also use a global state management library like Redux or Zustand to help manage the application state globally, including the state represented by query parameters. This can be particularly useful for more complex applications.
For more persistent state management across page reloads, you can store query parameters in local storage or session storage and retrieve them when needed. This can be a good option when you need to preserve query parameters across multiple page loads.
Here are some strategies for preserving query parameters during navigation:
- 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.
Sources
- https://nextjs.org/docs/pages/api-reference/functions/use-router
- https://blog.logrocket.com/next-js-routechangestart-router-events/
- https://www.dhiwise.com/post/navigating-nextjs-query-params-a-comprehensive-guide
- https://nextjs.org/docs/app/building-your-application/routing/linking-and-navigating
- https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration
Featured Images: pexels.com