iTranslated by AI
To what extent can next/navigation be used in Next.js Pages Router?
When porting Next.js from Pages Router to App Router, it becomes necessary to replace useRouter from next/router.
If you have written logic such as fetching queries or parameters within components, you might occasionally encounter minor issues with shared components.
Regarding this replacement, instead of migrating to App Router all at once:
- Replace
useRouterfromnext/routerwithuseParamsoruseSearchParamsfromnext/navigationin components used on the Pages Router. - Once the replacement is finished, port them to App Router.
I thought that if this procedure could be followed, the migration could be performed relatively safely and would assist with the migration process.
Can next/navigation hooks be used in Pages Router?
While there is no explicit mention of such a migration path, I found the following description in the useParams documentation:
If used in Pages Router, useParams will return null on the initial render and updates with properties following the rules above once the router is ready.
Based on this, it seems reasonable to assume that its use in the Pages Router is also intended.
Also, looking at issues like the ones below, they are trying to maintain as much compatibility as possible:
Therefore, it seems basically fine to replace them beforehand.
How much of a difference is there?
From here, I will compare the differences between them.
In this case, we will compare based on a scenario: what values are obtained when accessing a page like
sample/a/b/c?d=e
for a route such as
sample/[p]/[[...q]].tsx?
Parameter-related
import { useRouter } from 'next/router'
const router = useRouter()
// Parameter-related
console.log(router.query)
// => {"d":"e","p":"a","q":["b","c"]}
import { useParams, useSearchParams } from 'next/navigation'
const params = useParams()
const searchParams = useSearchParams()
// Parameter-related
console.log(JSON.stringify(params))
// => {"p":"a","q":["b","c"]}
console.log(JSON.stringify(Object.fromEntries(searchParams ?? [])))
// => {"d":"e"}
- While
useRouter'squeryallowed for retrieving both dynamic parameters and query parameters together,next/navigationrequires you to retrieveuseParamsanduseSearchParamsseparately.- Since
useSearchParamsis retrieved in the form ofURLSearchParams, the example above converts it to an object usingObject.fromEntriesfor display purposes. - For more specific details about the return value of
useSearchParams, you should refer to the documentation.
- Since
Path-related
import { useRouter } from 'next/router'
const router = useRouter()
console.log(router.pathname)
// => /sample/[p]/[[...q]]
console.log(router.asPath)
// => /sample/a/b/c?d=e
import { usePathname } from 'next/navigation'
const pathname = usePathname()
console.log(pathname)
// => /sample/a/b/c
Regarding paths, there doesn't seem to be a direct equivalent, and it was difficult to retrieve the pre-transformed path like /sample/[p]/[[...q]]. Since this was occasionally used for conditional display in navigation-related logic, some alternative approach might need to be devised in those cases.
Navigation-related
Navigation-related functions such as push and back are mostly available in the useRouter hook of the same name within next/navigation, so they can be used.
However, the documentation doesn't mention their use in the Pages Router, so some caution may be required.
Other missing features
The following features did not seem to exist:
- Status properties such as
isReadyandisPreview - Locale-related properties
Summary
- For simple parameter fetching, it is practically possible to use
next/navigationproactively on the Pages Router. - Since specific behaviors do not match exactly, you should be cautious when applying this method to complex or special logic.
Discussion