2

I just used npx create-next-app to create a next.js 13 typescript app. I've removed all the example css and html and am trying to introduce MUI. My app/layout.tsx looks like this:

import { CssBaseline } from '@mui/material';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <CssBaseline />
        {children}
      </body>
    </html>
  )
}

Adding the CSSBaseline bit produces a whole bunch of errors about things missing from React imports. Reading online this is because React is being accessed from a server component, which the root layout component must be. Here's the error output:

Server Error
TypeError: 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

This error happened while generating the page. Any console logs will be displayed in the terminal window.
Call Stack
React
node_modules/@emotion/react/dist/emotion-element-6bdfffb2.esm.js (14:41)
(sc_server)/./node_modules/@emotion/react/dist/emotion-element-6bdfffb2.esm.js
file:///[...]/.next/server/app/page.js (1724:1)
__webpack_require__
file:///[...]/.next/server/webpack-runtime.js (33:42)
eval
webpack-internal:///(sc_server)/./node_modules/@emotion/styled/base/dist/emotion-styled-base.esm.js (8:72)
(sc_server)/./node_modules/@emotion/styled/base/dist/emotion-styled-base.esm.js
file:///[...]/.next/server/app/page.js (1768:1)
__webpack_require__
file:///[...]/.next/server/webpack-runtime.js (33:42)
eval
webpack-internal:///(sc_server)/./node_modules/@emotion/styled/dist/emotion-styled.esm.js (5:95)
(sc_server)/./node_modules/@emotion/styled/dist/emotion-styled.esm.js
file:///[...]/.next/server/app/page.js (1779:1)
__webpack_require__
file:///[...]/.next/server/webpack-runtime.js (33:42)
require
node_modules/@mui/styled-engine/node/index.js (46:37)

Shouldn't I be able to do this? What am I missing?

I feel like once I have this working that the rest will fall into place and I'll be able to build out my MUI app.

I considered porting the material-next-ts example from the pages router to the app router. But the version of emotion that is being used supports a much simpler default approach which seems to require zero setup so all of the hoops that the pages route jumps through in the example seems unnecessary. Would be awesome if the example was ported to the app router!

bluefeet
  • 381
  • 1
  • 7

1 Answers1

1

The guidance in the error message will resolve the issue:

TypeError: 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

Try adding the 'use client' directive to the top of your app/layout.tsx. Here's an explanation from the Next.js docs about why 'use client' is necessary:

Most React applications rely on context to share data between components, either directly via createContext, or indirectly via provider components imported from third-party libraries.

In Next.js 13, context is fully supported within Client Components, but it cannot be created or consumed directly within Server Components. This is because Server Components have no React state (since they're not interactive), and context is primarily used for rerendering interactive components deep in the tree after some React state has been updated.

And here's another section explaining that your app/layout.tsx is a Server Component by default:

To make the transition to Server Components easier, all components inside the App Router are Server Components by default, including special files and colocated components. This allows you to automatically adopt them with no extra work, and achieve great performance out of the box. You can also optionally opt-in to Client Components using the 'use client' directive.

Travis Hohl
  • 2,176
  • 2
  • 14
  • 15