Error: NextRouter was not mounted.

Next.js · updated 2026-11-03

Thrown when useRouter() from next/router runs in a component rendered by the App Router (the app directory). The pages router context it needs is not mounted there, so the hook fails as soon as the component renders.

 ⨯ Error: NextRouter was not mounted. https://nextjs.org/docs/messages/next-router-not-mounted
    at useRouter (node_modules/next/dist/client/router.js:146:15)
    at Header (./src/components/Header.tsx:9:30)

Quick fix

In the app directory, import useRouter, usePathname and useSearchParams from 'next/navigation' instead of 'next/router'. The new router has no pathname, query or events on the router object: read them with usePathname() and useSearchParams().

  1. Replace import { useRouter } from 'next/router' with import { useRouter } from 'next/navigation'.
  2. Swap router.pathname for usePathname() and router.query for useSearchParams() (or the page params prop).
  3. Mark the component 'use client'; these hooks only run in Client Components.
  4. For router.events (route change tracking), use a usePathname/useSearchParams effect instead.
  5. Shared components used by both pages/ and app/ need to pick one router or receive the values as props.
typescript
'use client';
import { useRouter, usePathname, useSearchParams } from 'next/navigation';

export function Header() {
  const router = useRouter();          // push, replace, back, refresh
  const pathname = usePathname();      // was router.pathname
  const params = useSearchParams();    // was router.query
  return <button onClick={() => router.push('/orders')}>{pathname} {params.get('tab')}</button>;
}

Why it happens

Migrating from the pages directory

Components copied from pages/ still import next/router. They worked there and fail the first time an app/ route renders them.

A shared component used in both routers

A header or layout component used by pages/ and app/ routes can only use one router API, so it breaks in whichever one it was not written for.

A library that uses next/router internally

Older versions of some UI, analytics and auth libraries call next/router. Upgrading the library or wrapping it is the fix.

Other fixes

  • Search the codebase for "next/router" imports under app/ and components it renders.
  • In tests, mock next/navigation for components that moved to the App Router.

Same error, other wording

  • Error: invariant expected app router to be mounted
  • Error: useRouter only works in Client Components. Add the "use client" directive at the top of the file to use it.

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the 'NextRouter was not mounted' errors in production, list the components and libraries importing next/router that render in the app directory, and switch them to next/navigation hooks.

Plans from $29/moSee what your agent readsSee the setupCancel any time from the billing portal

Related errors

References: Next.js docs: NextRouter was not mounted, Next.js docs: useRouter (next/navigation)