Skip to main content

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

pathname
string
Current pathname (without basePath or query).
router.pathname  // "/blog/[slug]"
route
string
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" }
asPath
string
Full URL path including query string.
router.asPath  // "/blog/hello-world?author=john"
basePath
string
Configured base path from next.config.js.
router.basePath  // "/docs" or ""
locale
string | undefined
Current locale (i18n).
router.locale  // "en" or "fr"
locales
string[] | undefined
All configured locales.
router.locales  // ["en", "fr", "de"]
defaultLocale
string | undefined
Default locale.
router.defaultLocale  // "en"
isReady
boolean
Whether the router is ready (always true in vinext).
if (router.isReady) {
  // Router fields are populated
}
isPreview
boolean
Whether in preview mode (always false in vinext).
isFallback
boolean
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().
back
() => void
Navigate to the previous page.
<button onClick={() => router.back()}>Go Back</button>
reload
() => void
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
})
events
RouterEvents
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
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.

Scroll Control

// 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 RouterApp Router
useRouter()useRouter() (next/navigation)
router.pathnameusePathname()
router.queryuseSearchParams()
router.push()router.push()
router.back()router.back()

Source

View source code → Implementation: /home/daytona/workspace/source/packages/vinext/src/shims/router.ts