How to Fix: TypeError: createContext only works in Client Components. Add the “use client” directive at the top of the file to use it

4 min read

Fixing the Next.js Error: createContext only works in Client Components

This error appears when a component using React context is being treated as a Server Component in the Next.js App Router. Since createContext relies on client-side React features, Next.js throws an error unless that file is explicitly marked with the “use client” directive.

Understanding the Root Cause

In Next.js App Router, files inside the app directory are Server Components by default. That means they run on the server unless you opt into client-side behavior.

The problem is that createContext, like hooks such as useState and useEffect, belongs to the client-side React runtime. If a layout, provider, or shared wrapper creates a context without being marked as a client component, Next.js detects the mismatch and throws:

TypeError: createContext only works in Client Components. Add the “use client” directive at the top of the file to use it.

This often happens when:

  • A context provider is added directly in app/layout.tsx
  • A third-party library internally uses React context
  • A component imported into a server file depends on client-only APIs

In short, the issue is not with React context itself. The issue is that the file using it is being rendered in the wrong component boundary.

Step-by-Step Solution

The fix is to move any context creation or context provider rendering into a dedicated Client Component.

1. Create a client provider file

If you have a provider, place it in its own file and add the directive at the very top:

'use client'

import { createContext, useContext, useState } from 'react'

const AppContext = createContext(null)

export function AppProvider({ children }) {
  const [value, setValue] = useState('hello')

  return (
    <AppContext.Provider value={{ value, setValue }}>
      {children}
    </AppContext.Provider>
  )
}

export function useAppContext() {
  return useContext(AppContext)
}

2. Use the provider inside your server layout

Your app/layout.tsx can remain a Server Component, but it can render a client provider inside it:

import { AppProvider } from './providers'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <AppProvider>{children}</AppProvider>
      </body>
    </html>
  )
}

3. If the error comes from a page or component, mark that file as client

If the component itself uses createContext, useState, or browser APIs, add:

'use client'

at the top of that file, before any imports.

4. Check third-party providers

Some libraries for themes, authentication, UI state, or analytics use React context internally. Wrap them in a dedicated client component:

'use client'

import { ThemeProvider } from 'some-library'

export function Providers({ children }) {
  return <ThemeProvider>{children}</ThemeProvider>
}

Then use it in your layout:

import { Providers } from './providers'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  )
}

5. Restart the dev server

After changing component boundaries, restart the local server to clear stale compilation state:

yarn dev

If you are reproducing this from a fresh starter created via the official Next.js installation guide, also verify that no additional provider or package was introduced into the default scaffold.

Common Edge Cases

  • The directive is not the first line: 'use client' must appear before imports or other statements.
  • You added it to the wrong file: The erroring file may import another component that uses createContext. Fix the actual source file.
  • A third-party package is the real cause: Libraries like theme, auth, or state providers may require a client wrapper even if your own code does not call createContext directly.
  • Mixing server-only modules into client components: After adding 'use client', imports such as filesystem access or server utilities may fail because client components cannot use server-only code.
  • Layout became unnecessarily client-side: Avoid marking the entire root layout as client unless needed. Keep the server/client boundary as small as possible for better performance.
  • Hydration mismatch after the fix: If your provider initializes different values on server and client, you may see hydration warnings next. Make sure initial rendered output is consistent.

FAQ

Why does this happen in the App Router but not in older Next.js setups?

In the App Router, components are server-first by default. In older Pages Router apps, many components were rendered on the client by default, so this boundary was less visible.

Should I add 'use client' to app/layout.tsx?

Usually, no. A better pattern is to keep layout.tsx as a Server Component and place all context providers inside a nested client wrapper such as providers.tsx.

How do I know which file is causing the error?

Check the stack trace in the terminal or browser overlay. Look for the first file in your project that directly uses createContext, useState, useEffect, or a third-party provider. That file should usually be converted into a Client Component.

For most projects, the reliable fix is simple: isolate React context inside a small provider component, put “use client” at the top, and render that provider from your server layout. That preserves the benefits of Server Components while resolving the context error cleanly.

Leave a Reply

Your email address will not be published. Required fields are marked *