Documentation Index
Fetch the complete documentation index at: https://mintlify.com/cloudflare/vinext/llms.txt
Use this file to discover all available pages before exploring further.
The next/router module provides the Pages Router API, including the useRouter hook and default Router singleton for programmatic navigation.
Import
import { useRouter } from 'next/router'
import Router from 'next/router'
useRouter Hook
Returns a router instance with navigation methods and current route state.
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
return (
<div>
<p>Current path: {router.pathname}</p>
<p>Query: {JSON.stringify(router.query)}</p>
<button onClick={() => router.push('/about')}>
Go to About
</button>
</div>
)
}
Router Object
Properties
Current pathname (without basePath or query).router.pathname // "/blog/[slug]"
Current route pattern (with dynamic segments).router.route // "/blog/[slug]"
query
Record<string, string | string[]>
Query parameters and dynamic route params.// URL: /blog/hello-world?author=john
router.query // { slug: "hello-world", author: "john" }
Full URL path including query string.router.asPath // "/blog/hello-world?author=john"
Configured base path from next.config.js.router.basePath // "/docs" or ""
Current locale (i18n).router.locale // "en" or "fr"
All configured locales.router.locales // ["en", "fr", "de"]
Default locale.router.defaultLocale // "en"
Whether the router is ready (always true in vinext).if (router.isReady) {
// Router fields are populated
}
Whether in preview mode (always false in vinext).
Whether the page is in fallback mode (ISR).
Methods
push
(url, as?, options?) => Promise<boolean>
Navigate to a new URL (pushes history entry).await router.push('/about')
await router.push({ pathname: '/user/[id]', query: { id: '123' } })
await router.push('/post', undefined, { scroll: false })
await router.push('/', undefined, { locale: 'fr' })
Parameters:
url: string | UrlObject — Destination
as?: string — URL mask (legacy)
options?: { shallow?: boolean; scroll?: boolean; locale?: string }
Returns: Promise<boolean> — true on success
replace
(url, as?, options?) => Promise<boolean>
Navigate to a new URL (replaces history entry).await router.replace('/login')
await router.replace('/dashboard', undefined, { shallow: true })
Same parameters as push().
Navigate to the previous page.<button onClick={() => router.back()}>Go Back</button>
Hard reload the current page.<button onClick={() => router.reload()}>Reload</button>
prefetch
(url: string) => Promise<void>
Prefetch a page for faster navigation.<div onMouseEnter={() => router.prefetch('/dashboard')}>
Hover to prefetch
</div>
beforePopState
(cb: BeforePopStateCallback) => void
Register a callback to run before browser back/forward navigation.router.beforePopState(({ url, as, options }) => {
// Return false to prevent navigation
if (hasUnsavedChanges()) {
alert('You have unsaved changes!')
return false
}
return true
})
Event emitter for route changes.useEffect(() => {
const handleStart = (url) => console.log('Navigating to', url)
const handleComplete = (url) => console.log('Navigated to', url)
router.events.on('routeChangeStart', handleStart)
router.events.on('routeChangeComplete', handleComplete)
return () => {
router.events.off('routeChangeStart', handleStart)
router.events.off('routeChangeComplete', handleComplete)
}
}, [])
Events:
routeChangeStart(url: string) — Before navigation starts
routeChangeComplete(url: string) — After navigation completes
routeChangeError(err: Error, url: string) — On navigation error
Router Singleton
The default export provides a router singleton for use outside components:
import Router from 'next/router'
// Usage in utility functions
export async function logout() {
await clearSession()
await Router.push('/login')
}
Methods and events are identical to useRouter().
UrlObject
Construct URLs programmatically:
interface UrlObject {
pathname?: string
query?: Record<string, string>
}
router.push({
pathname: '/blog/[slug]',
query: { slug: 'hello-world', author: 'john' }
})
// Navigates to: /blog/hello-world?author=john
Navigation Options
interface TransitionOptions {
shallow?: boolean // Update URL without re-fetching (deprecated)
scroll?: boolean // Scroll to top after navigation (default: true)
locale?: string // Navigate to a specific locale
}
Shallow Routing
Update the URL without triggering a full page navigation:
router.push('/?filter=tech', undefined, { shallow: true })
Deprecated in App Router — Use window.history.pushState() instead.
// Don't scroll to top (stay at current position)
router.push('/page', undefined, { scroll: false })
Route Events
Listen for navigation events:
import { useEffect } from 'react'
import { useRouter } from 'next/router'
export default function Page() {
const router = useRouter()
useEffect(() => {
function handleRouteChange(url) {
console.log('App is changing to: ', url)
}
router.events.on('routeChangeComplete', handleRouteChange)
return () => {
router.events.off('routeChangeComplete', handleRouteChange)
}
}, [router.events])
return <div>Page content</div>
}
Available Events
- routeChangeStart(url) — Fires before navigation
- routeChangeComplete(url) — Fires after navigation succeeds
- routeChangeError(err, url) — Fires on navigation error
Hash Navigation
Navigate to hash links:
router.push('#section-2')
router.push('/page#section-2')
Scroll to the target element automatically.
External URLs
External URLs trigger full page navigation:
router.push('https://example.com')
// Same as: window.location.href = 'https://example.com'
Dynamic Routes
Access dynamic route parameters via router.query:
// File: pages/blog/[slug].tsx
import { useRouter } from 'next/router'
export default function Post() {
const router = useRouter()
const { slug } = router.query
return <h1>Post: {slug}</h1>
}
Catch-All Routes
// File: pages/docs/[...slug].tsx
export default function Docs() {
const router = useRouter()
const { slug } = router.query
// slug is an array: ["getting-started", "installation"]
return <div>Path: {slug?.join('/')}</div>
}
i18n Routing
Navigate with locale support:
router.push('/', undefined, { locale: 'fr' })
router.push('/', undefined, { locale: false }) // Use default locale
basePath Support
If basePath is configured, it’s automatically handled:
// next.config.js
module.exports = { basePath: '/docs' }
router.push('/api') // Navigates to /docs/api
router.pathname // Returns /api (without basePath)
Limitations
Server-side routing: useRouter can only be called in client components. Use getServerSideProps to read route params on the server.
Shallow routing: Only updates query and asPath. Full page navigation still occurs if the route pattern changes.
Migration to App Router
App Router equivalents:
| Pages Router | App Router |
|---|
useRouter() | useRouter() (next/navigation) |
router.pathname | usePathname() |
router.query | useSearchParams() |
router.push() | router.push() |
router.back() | router.back() |
Source
View source code →
Implementation: /home/daytona/workspace/source/packages/vinext/src/shims/router.ts