Fix: 'NextRouter was not mounted' in Next.js App Directory
Getting the 'NextRouter was not mounted' error? Learn why next/router fails in the App Router and how to correctly use next/navigation for Next.js 14 and 15.
FlowQL Team
AI Search Optimization Experts
You’re adding a simple "Back" button or a manual redirect to your Next.js app. You do what you’ve always done: import { useRouter } from 'next/router'. You call the hook, you hit "Save," and your screen turns red with a cryptic error: "Error: NextRouter was not mounted. https://nextjs.org/docs/messages/next-router-not-mounted"
This is the "Legacy Hook Trap."
If you are a "Vibe Coder" building with the help of AI, you hit this error almost every time you try to handle navigation. Because AI models are trained on years of Next.js "Pages Router" documentation, they almost always default to the old next/router import.
But in the App Router environment, next/router is essentially a foreign language. It doesn't understand the new routing architecture, and it refuses to "mount" in the context of the /app directory.
In this guide, we’ll explain the fundamental difference between the old and new navigation hooks, show you the correct way to redirect in the App Router, and provide the best practices for both Client and Server components.
The Root Cause: next/router vs. next/navigation
To fix the crash, you have to understand the split.
In Next.js 13, Vercel introduced a completely new routing system based on React Server Components. To make this work, they had to rewrite the underlying "Router" from scratch.
next/router: This belongs to the Pages Router (the/pagesfolder). It is synchronous and tightly coupled to the old client-side navigation logic.next/navigation: This belongs to the App Router (the/appfolder). It is designed to work with both Server and Client components and supports features like Streaming and Transitions.
If your file is inside the /app directory, you cannot use next/router.
The Solution: Switching to the new useRouter Hook
If you are inside a Client Component (a file with 'use client' at the top), you still use a useRouter hook, but you must import it from the new package.
The WRONG Way (Legacy)
'use client';
import { useRouter } from 'next/router'; // ❌ This will crash!
The RIGHT Way (Modern)
'use client';
import { useRouter } from 'next/navigation'; // ✅ Correct for App Router
export default function BackButton() {
const router = useRouter();
return (
<button onClick={() => router.back()}>
Go Back
</button>
);
}
Note: The new useRouter from next/navigation has a slightly different API. For example, it no longer has the router.query object. To get query parameters, you must use the useSearchParams hook. For more on that transition, see our guide on async params in Next.js 15.
Server-Side Navigation: Using redirect()
One of the best features of the App Router is the ability to handle navigation directly on the server before any JavaScript hits the browser.
If you are in a Server Component (the default), you don't use hooks at all. Instead, you use the redirect function.
// page.tsx (Server Component)
import { redirect } from 'next/navigation';
export default async function ProfilePage() {
const session = await getSession();
if (!session) {
redirect('/login'); // ✅ Fast, server-side redirect
}
return <div>Welcome to your profile</div>;
}
This is much better for performance and SEO because the browser never even attempts to load the restricted page—it gets a 307 redirect instruction from the server immediately.
Common Error: Using navigation hooks in Server Components
If you try to use useRouter() or usePathname() in a file without 'use client', Next.js will throw an error like: "You're importing a component that needs use client."
The Rule: If you need the router to respond to a user clicking a button, move that logic to a "Leaf Component" and mark it as 'use client'. For a deeper dive into this architecture, check our Next.js 'use client' SEO guide.
Best Practices for Programmatic Navigation
To avoid navigation bugs in the future, follow these three rules:
- Prefer
<Link>: Whenever possible, use thenext/linkcomponent. It handles prefetching and accessibility automatically. Only useuseRouterwhen you need to navigate after a complex event (like a successful form submission). - Redirect Early: If you know a user needs to go elsewhere (e.g., they aren't logged in), use
redirect()in the Server Component. Don't wait for the page to load and then use a client-side hook. - Check Your Imports: If you see "NextRouter was not mounted," the first thing you should do is check the very first line of your file. Change
routertonavigation.
FlowQL: Modernizing Your Next.js Stack
The transition from the Pages Router to the App Router is one of the most complex migrations in modern web history. AI assistants are great at boilerplate, but they consistently struggle with the API Nuances between these two paradigms. They will write code that looks 99% correct but fails in production because of a single legacy import.
At FlowQL, we help companies modernize their Next.js applications. We provide the senior technical oversight to audit your navigation logic, fix your "not mounted" errors, and ensure your routing is both fast and SEO-friendly.
If your "Vibe" is broken by a legacy hook, it's time for a human expert to look at the imports.
Conclusion
The "NextRouter was not mounted" error is a clear signal that you are mixing old and new patterns. By switching your imports to next/navigation and utilizing server-side redirects, you can build a stable, high-performance App Router application.
Your Action Plan:
- Search your codebase for
from 'next/router'. - If the file is in
/app, change it tofrom 'next/navigation'. - If the file is a Server Component, replace the hook with the
redirect()function.
Don't let a legacy hook crash your ship. [Book a session with FlowQL] and let’s get your Next.js navigation perfectly synced.
FAQ: Next.js Router Troubleshooting
Q: Can I use both next/router and next/navigation?
A: Only if you have both a /pages and an /app directory in your project. Inside a specific file, you must choose one based on which directory it lives in.
Q: Where is router.query in the App Router?
A: It's gone. In the App Router, use the useSearchParams() hook in Client Components or the searchParams prop in Server Components.
Q: Does redirect() work in Server Actions?
A: Yes! redirect() is the preferred way to send users to a new page after a Server Action completes (like a login or a post creation).
Subscribe to our blog
Get the latest guides and insights delivered to your inbox.
Join the FlowQL waitlist
Get early access to our AI search optimization platform.
Related Articles
Fix: params are undefined in Next.js App Router Server Component
params undefined in your Next.js server component? Learn how to handle the async breaking change in Next.js 15 and properly await your dynamic route data.
Fix 'Hydration Failed Because the Initial UI Does Not Match' in Next.js 14 (2025 Guide)
Next.js hydration failed error? This comprehensive guide covers 8 root causes, 5 quick fixes, systematic debugging workflow, and when AI tools can't see the invisible wall between server and client.
Fix "Text Content Does Not Match Server-Rendered HTML" in Next.js
Solve the dreaded hydration mismatch error in Next.js. Learn why server HTML differs from client renders and how to fix it with useEffect, suppressHydrationWarning, and proper nesting.