vercel/next.js · error · Error

No router instance found. You should only use "next/router"

Error message

No router instance found.
You should only use "next/router" on the client side of your app.

What it means

`getRouter()` in router.ts:74-82 returns the Pages Router singleton. If `singletonRouter.router` is null (never initialized via `createRouter`), it throws this `Error`. The singleton is only populated client-side during hydration, so accessing it on the server or before initialization is the bug the message points at.

Source

Thrown at packages/next/src/client/router.ts:79

  'reload',
  'back',
  'prefetch',
  'beforePopState',
] as const

// Events is a static property on the router, the router doesn't have to be initialized to use it
Object.defineProperty(singletonRouter, 'events', {
  get() {
    return Router.events
  },
})

function getRouter(): Router {
  if (!singletonRouter.router) {
    const message =
      'No router instance found.\n' +
      'You should only use "next/router" on the client side of your app.\n'
    throw new Error(message)
  }
  return singletonRouter.router
}

urlPropertyFields.forEach((field) => {
  // Here we need to use Object.defineProperty because we need to return
  // the property assigned to the actual router
  // The value might get changed as we change routes and this is the
  // proper way to access it
  Object.defineProperty(singletonRouter, field, {
    get() {
      const router = getRouter()
      return router[field] as string
    },
  })
})

coreMethodFields.forEach((field) => {

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Use `next/navigation`'s `useRouter` in the App Router, not `next/router`.
  2. Only call `next/router` inside client-only code paths (event handlers, effects), guarded by `typeof window !== 'undefined'` if needed.
  3. Ensure Pages Router pages are hydrated so `createRouter` runs before any router access.

Example fix

// before — App Router Server Component
import router from 'next/router'
export default function Page() { router.push('/x') /* throws */ }

// after — App Router Client Component
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
  const router = useRouter()
  return <button onClick={() => router.push('/x')}>go</button>
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Guard server/client boundaries before touching next/router.
function canUsePagesRouter(): boolean {
  return typeof window !== 'undefined' && !!singletonRouterAvailable()
}

Type guard

function isBrowser(): boolean {
  return typeof window !== 'undefined'
}
// Usage:
if (isBrowser()) { const router = require('next/router').default }

Prevention

When it happens

Trigger: Importing `next/router` and calling `useRouter()`/`router.push()` in code that runs on the server (Server Component, `getStaticProps`, `getServerSideProps`, a Node script) or in the browser before the router singleton has been created.

Common situations: Using `next/router` (Pages Router API) inside an App Router Server Component; calling router methods at module top-level on the server; SSR of a component that calls `router.push` during render.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/7ef93a0801615b27. Report an issue: GitHub.