If you build with Next.js long enough, you will encounter the same handful of errors again and again. Most of them are not bugs in Next.js itself. They happen because the App Router works differently from a traditional React application. Some code runs on the server, some runs in the browser, and Next.js expects you to understand where each piece of code belongs.
The good news is that once you understand why these errors happen, they often take minutes to fix instead of hours. Here are some of the most common errors developers encounter, why they happen, and how to fix them.
8 Common Errors in Next.js and How to Fix Them
1. "window is not defined" or "document is not defined"
This is one of the most common Next.js errors, and almost every developer encounters it at some point.
Why it happens: Next.js can render your pages on the server before sending the HTML to the browser. The server does not have access to browser-specific objects such as 'window' or 'document'. If your code tries to access 'localStorage', read 'window', or query an element from the page while the component is rendering on the server, Next.js can throw this error.
How to fix it: There are two common approaches. First, you can delay browser-specific code until the component has mounted in the browser by using React's 'useEffect' hook. This works well when only a small part of the component needs access to browser APIs. Second, for components that depend heavily on the browser, such as charts, maps, or rich text editors, you can load them dynamically and disable server-side rendering for that component. Next.js provides a built-in dynamic import feature for this purpose.
2. Hydration mismatch ("Text content does not match server-rendered HTML")
Why it happens: During hydration, React compares the HTML generated on the server with what it expects to render in the browser. If the two outputs do not match, you may get a hydration error.
Common causes include:
- Rendering the current date, time, or a random value, since these can differ between the server and browser
- Reading from `localStorage` or checking the user's timezone while the page is rendering instead of after the component has mounted
- Invalid HTML nesting, such as placing a block-level element inside a paragraph
- A browser extension modifying the page before React finishes hydrating it
How to fix it: The most reliable approach is to delay unstable or browser-specific content until after the component has mounted. You can use a simple `mounted` state and render the dynamic content only after that state changes.
If the mismatch is genuinely harmless and caused by something outside your control, Next.js and React also provide ways to suppress a hydration warning on a specific element. However, this should be used sparingly because it hides the warning rather than fixing the underlying mismatch.
3. "use client" placed too high in the component tree
This may not throw an error, but it is a common performance mistake in App Router projects, so it deserves a place on this list.
Why it happens: When you add the `"use client"` directive to a file, that file becomes a Client Component, and its imported dependencies may become part of the client-side JavaScript bundle. Developers sometimes mark an entire page as a Client Component simply because one button on the page needs a click handler. This can result in more JavaScript being sent to the browser and can reduce some of the performance benefits of Server Components.
How to fix it: Keep pages and layouts as Server Components by default when possible. Move only the interactive part that needs browser-side functionality - such as a button, toggle, or form field - into a separate component and mark that component with `"use client"`. This keeps the client-side JavaScript smaller while allowing the interactive elements to work normally.
4. Module not found: Can't resolve 'fs' (or another Node.js module)
Why it happens: Some Node.js modules, such as the file system module (`fs`), are available only in the server environment. They cannot run in the browser. If a Client Component imports one of these modules, either directly or through a third-party package, the build can fail.
How to fix it: Keep file system, database, and other server-only operations inside server-side code, such as Server Components, Server Actions, or Route Handlers, depending on the use case. This prevents those modules from being included in the browser bundle.
If a third-party package is causing the problem, first check whether it provides a browser-compatible version or whether it needs to be used only on the server. Avoid simply excluding a required Node.js module from the client build unless you are certain the code will never execute in the browser.
5. CORS errors on API routes
Why it happens: If a website or application on a different origin tries to call your API route, the browser may block the response unless the API provides the appropriate Cross-Origin Resource Sharing (CORS) headers.
This can also happen during local development when the frontend and API are running on different ports.
How to fix it: Configure the appropriate CORS headers in your API response. These headers should specify which origins are allowed and which HTTP methods, such as 'GET' or 'POST', can be used.
If multiple API routes require the same CORS rules, you can centralize the configuration where appropriate instead of repeating the same headers across every route.
6. "getStaticPaths is not a function" or missing static paths
Why it happens: 'getStaticPaths' belongs to the older Pages Router and is not used in the App Router. Developers migrating an older project or following outdated tutorials may try to use `getStaticPaths` in an App Router project and wonder why it does not work.
In the App Router, the equivalent approach for generating static pages for dynamic routes is 'generateStaticParams'.
How to fix it: If you are using the App Router, use 'generateStaticParams' in your dynamic route. For example, a dynamic route such as 'app/products/[id]/page.js' can export `generateStaticParams` to specify which paths should be generated at build time.
If you are still using the Pages Router, continue using 'getStaticPaths' in the appropriate dynamic page file.
7. Unprotected Server Actions
Why it happens: Server Actions run on the server, but they can be invoked through requests from the client. You should not assume that frontend checks or UI restrictions are enough to protect them.
If a Server Action performs a sensitive operation without verifying the user's identity and permissions, an unauthorized user could potentially trigger that operation.
How to fix it: Each Server Action that handles protected data should perform its own authorization checks. Verify that the user is authenticated and has permission to perform the requested action on the specific record or resource.
You should also validate incoming data on the server. Data validation is important, but it does not replace authentication and authorization checks.
Treat Server Actions as server-side entry points that require the same security considerations as other endpoints.
8. Middleware not running, or "Dynamic Server Usage" errors
Two different issues are often grouped together here.
Middleware not running: Middleware may not execute if the file is in the wrong location, uses an incorrect filename for the version of Next.js you're using, or has an incorrect matcher configuration. Next.js has also introduced changes to the naming and recommended usage of middleware in newer versions, so older tutorials may not match your current setup.
Dynamic Server Usage errors: These can occur when a route is expected to be statically rendered but uses request-specific information, such as cookies or headers.
How to fix it: If middleware is not triggering, first check the file name, location, matcher configuration, and the documentation for your specific Next.js version.
For dynamic rendering errors, identify the code that depends on request-specific information. Depending on your application's requirements, you may need to move that logic to the appropriate server-side location or configure the route to use dynamic rendering.
Get Expert Help With Next.js Development
For businesses building or maintaining a Next.js website, working with an experienced web development agency in Kerala can help identify technical issues early and ensure the application is built with the right architecture, performance, and security practices from the start. WebCastle Media provides web development services for businesses that need scalable and reliable websites and web applications built around their specific requirements.
Final Thoughts
Most Next.js errors come down to one fundamental question: Is this code running on the server or in the browser, and does it belong there?
Once that distinction becomes second nature, many of the errors on this list become much easier to diagnose and fix. Keep Server Components on the server when possible, keep Client Components focused on interactive functionality, and perform authentication and authorization checks inside protected Server Actions.
Understanding these fundamentals can help developers build Next.js applications that are easier to maintain, more secure, and more efficient.






