You’re importing a component that needs useState

A Next.js Server Component used a browser-side React feature like useState, which only works in files marked as Client Components.

Next.js error overlay and terminal
You're importing a module that depends on `useState` into a React Server Component module. This API is only available in Client Components. To fix, mark the file (or its parent) with the `"use client"` directive. Learn more: https://nextjs.org/docs/app/api-reference/directives/use-client

Also appears as

  • You're importing a component that needs `useState`. This React Hook only works in a Client Component. To fix, mark the file (or its parent) with the `"use client"` directive.
  • You're importing a component that needs `useState`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive.
  • You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.
  • useState only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component
  • createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component

Prompt to fix it

Next.js fails with "You're importing a module that depends on `useState` into a React Server Component module" (older versions say "You're importing a component that needs useState"). Find the Server Component that uses the hook. Move only the interactive part into a separate Client Component file with "use client" as its first line, and keep the page or layout a Server Component that passes serializable props down. For third-party components that use hooks, add a small "use client" wrapper file. Don’t put "use client" on page.tsx or layout.tsx to make the error go away.

Paste into Layerwise or any AI coding tool.

What it means

In the Next.js App Router, every component is a Server Component unless its file starts with 'use client'. Server Components run on the server to produce HTML and never run in the browser, so they can’t hold state, run effects, or handle clicks. Hooks such as useState, useEffect, and useRouter from next/navigation need a Client Component.

'use client' marks a boundary. The file that has it, and everything that file imports, becomes client code. Add it to the smallest component that needs interactivity, such as a button or a form, and keep the page itself a Server Component so its data loading stays on the server.

Putting 'use client' at the top of page.tsx or layout.tsx makes this error go away, but it turns the whole route into client code. Then async components, metadata exports, and secret environment variables stop working there, and you trade this error for new ones.

Common causes

  • An AI tool added useState or useEffect to a page or layout file, which is a Server Component by default.
  • A component file that uses hooks is missing 'use client', or has it below the imports, where Next.js rejects it.
  • A Server Component imports a library component that uses hooks but doesn’t ship with 'use client'.
  • A Server Component calls useRouter, usePathname, or useSearchParams from next/navigation.

How to fix it

  1. Open the file named in the error and find the hook it lists.
  2. Move the interactive part into its own file with 'use client' as the first line, above the imports.
  3. Import that component into the Server Component and pass it data as props. Props must be serializable: strings, numbers, plain objects, and arrays.
  4. For a third-party component without the directive, create a small file with 'use client' that imports it and exports it again.
  5. In a page, read URL data from the params and searchParams props instead of usePathname or useSearchParams.

Example fix

// app/posts/[id]/like-button.tsx
'use client';

import { useState } from 'react';

export function LikeButton({ initialLikes }: { initialLikes: number }) {
  const [likes, setLikes] = useState(initialLikes);
  return <button onClick={() => setLikes(likes + 1)}>Like ({likes})</button>;
}

// app/posts/[id]/page.tsx stays a Server Component.
import { LikeButton } from './like-button';

export default async function PostPage({
  params
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const post = await getPost(id);
  return <LikeButton initialLikes={post.likes} />;
}
All errors
ReferenceError: window is not defined

ReferenceError: window is not defined

Code that only works in a browser ran on the server, where there is no window, document, or localStorage.

Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used: - A server/client branch `if (typeof window !== 'undefined')`. - Variable input such as `Date.now()` or `Math.random()` which changes each time it's called. - Date formatting in a user's locale which doesn't match the server. - External changing data without sending a snapshot of it along with the HTML. - Invalid HTML tag nesting. It can also happen if the client has a browser extension installed which messes with the HTML before React loaded. https://react.dev/link/hydration-mismatch

Hydration failed

The HTML the server sent didn’t match what React rendered first in the browser, so React threw that part away and rebuilt it on the client.

Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons: 1. You might have mismatching versions of React and the renderer (such as React DOM) 2. You might be breaking the Rules of Hooks 3. You might have more than one copy of React in the same app See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.

Invalid hook call

A hook such as useState ran somewhere React can’t track it, or the app loaded two copies of React that don’t know about each other.

Too many re-renders. React limits the number of renders to prevent an infinite loop.

Too many re-renders

A component changes its own state while it renders, so React renders it again and again until it stops the loop.

Build with an agent that checks its work

The Layerwise agent clicks through the live preview and reads the console, so it catches errors before you do.