Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I created a brand new Next.js application that uses the app folder. I then installed Materiel UI and started using the example given on the doc. But I'm getting this error:

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

Here is the example from the doc in my code:

import Button from "@mui/material/Button";

export default function Home() {
  return (
    <div>
      <Button variant="contained">Hello World</Button>
    </div>
  );
}

I'm expecting to have the button displayed on my page. I understand that adding "use client" at the top will fix the error, but I want my page to be rendred on the server.

like image 551
Drew McCarty Avatar asked Nov 16 '25 03:11

Drew McCarty


2 Answers

Obviously, the button you are importing is using client-side hooks, createContext in this case. For this to work, you need to add "use client" at the top of the file. But it would mean the page becomes a Client Component, and no longer a Server Component.

If that bothers you, you could, for example, create a lib folder at the same level as app in which you add a mui.js file, like so:

// lib/mui.js

"use client";

export * from "@mui/material";

And you import it from there (this way, other parts of the page are still Server Components):

// app/page.js

import { Button } from "../lib/mui";

export default function Home() {
  return (
    <div>
      <Button variant="contained">Hello World</Button>
    </div>
  );
}

Side note, you may get a similar error while setting up a context. It means you are trying to set it up in a Server Component. The guideline is to add it in its own "use client" marked file:

// app/theme-provider.tsx

"use client";

import { createContext } from "react";

export const ThemeContext = createContext("");

export default function ThemeProvider({ children }) {
  return (
    <ThemeContext.Provider value="dark">
      {children}
    </ThemeContext.Provider>
  );
}

And import it from there:

// app/layout.js

import ThemeProvider from './theme-provider';
 
export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <ThemeProvider>{children}</ThemeProvider>
      </body>
    </html>
  );
}

For an even more elaborate answer, check out this thread.

like image 174
yousoumar Avatar answered Nov 18 '25 15:11

yousoumar


Make sure you import your own ThemeProvider, not the ThemeProvider from next-themes

import { ThemeProvider } from '@/components/theme-provider'
like image 21
Russo Avatar answered Nov 18 '25 16:11

Russo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!