How to Fix: TypeError: createContext only works in Client Components. Add the “use client” directive at the top of the file to use it
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.
Table of Contents
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
createContextdirectly. - 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.