Solving Next.js error: NextRouter was not mounted

Updated: May 19, 2023 By: Frienzied Flame 2 comments

This concise article shows you how to fix a common error related to NextRouter in Next.js

The Problem

When working with Next.js 13 or a newer version of the framework, you might run into the following error:

Unhandled Runtime Error
Error: NextRouter was not mounted.

Screenshot:

The cause of the error is that you imported the useRouter hook from next/router.

The Solution

To solve the mentioned problem, you should always import useRouter from next/navigation instead of next/router when working with pages and components inside the app directory.

Other important things you should be aware of to avoid potential errors with useRouter:

  • All components in the app directory are server components by default, but hooks are only available on the client side. Thus, you must add the use client directive at the top of every file that involves hooks.
  • The pathname and query properties were removed from the router object. You should use the usePathname() and useSearchParams() hooks instead.

Below is a complete and working example that demonstrates how to correctly and safely use the useRouter() in Next.js 13 and above.

// app/pages.tsx

'use client';
import { useRouter } from 'next/navigation';

export default function Home() {
  const router = useRouter();

  const refreshPage = () => {
    router.refresh();
  };

  return (
    <div style={{ padding: 30 }}>
      <h1 style={{ fontSize: 40 }}>Welcome to Sling Academy</h1>
      <button
        style={{
          padding: '7px 30px',
          background: 'green',
          color: 'white',
        }}
        onClick={refreshPage}
      >
        Refresh this page
      </button>
    </div>
  );
}

Screenshot:

If you’re working for a large company, it’s very likely that your boss requires you (or your team) to do unit tests when developing Next.js projects. This is the main point of the next section.

Mocking NextRoter for Unit Test

When you perform unit tests by using a library like Jest, you should mock NextRouter to get through the potential errors related to this hook (including the problem above). A great solution is to use a package named next-router-mock. Install it by running the following command:

npm i next-router-mock -D

Then use it as the following instructions:

// Jest Configuration
// For unit tests, the next-router-mock module can be used as a drop-in replacement for next/router:
jest.mock('next/router', () => require('next-router-mock'));

// You can do this once per spec file, or you can do this globally using setupFilesAfterEnv.

An alternative solution is to use the jest.mock() function to replace the next/navigation or next/router module with a mock implementation.

Example:

// mock useRouter
jest.mock('next/router', () => ({
  useRouter: jest.fn()
}));

// setup a new mocking function for push method
const pushMock = jest.fn();

// mock a return value on useRouter
useRouter.mockReturnValue({
  query: {},
  // return mock for push method
  push: pushMock,
  // ... add the props or methods you need
});

That’s it. Happy coding & have a nice day!

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments