material-ui: Next.js build error when using Edge Runtime

Steps to reproduce ๐Ÿ•น

Link to live example:

Steps:

Current behavior ๐Ÿ˜ฏ

No response

Expected behavior ๐Ÿค”

No response

Context ๐Ÿ”ฆ

No response

Your environment ๐ŸŒŽ

npx @mui/envinfo
  Don't forget to mention which browser you used.
  Output from `npx @mui/envinfo` goes here.

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 26 (4 by maintainers)

Commits related to this issue

Most upvoted comments

@mj12albert thanks for the feedback and for looking at this, Iโ€™ve upgraded emotion and copied the new version of the ThemeRegistry from the example provided. Unfortunately Iโ€™m still seeing the error in the server logs - only for the routes marked as runtime = edge error TypeError: Cannot read properties of undefined (reading 'fontWeightBold')

Any updates on this? ๐Ÿ™

Use createTheme before passing the theme to ThemeProvider.

for example, const appTheme = createTheme(theme); <ThemeProvider theme={appTheme}> <CssBaseline /> {children} </ThemeProvider>

I have the same issue. However, in my case, itโ€™s not possible to replicate that in codesandbox because the error seems to only appear on NextJS, using edge runtime - which doesnโ€™t seem to be currently supported by the codesandbox engine. - and it seems to be caused by <CssBaseline />

The minimum repro step would include

/app/layout.js

import ThemeRegistry from "./ThemeRegistry";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
          <ThemeRegistry options={{ key: 'mui' }}>
            <div>{children}</div>
          </ThemeRegistry>
      </body>
    </html>
  );
}

export const metadata = {
  title: 'RootLayout',
}

ThemeRegistry.js

"use client"

import createCache from '@emotion/cache';
import { useServerInsertedHTML } from 'next/navigation';
import { CacheProvider } from '@emotion/react';
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import { createTheme } from "@mui/material";
import { theme as baseTheme } from '../theme/theme';
import { useState } from "react";

const theme = createTheme({
  ...baseTheme,
})

// This implementation is from emotion-js
// https://github.com/emotion-js/emotion/issues/2928#issuecomment-1319747902
export default function ThemeRegistry(props) {
  const { options, children } = props;

  const [{ cache, flush }] = useState(() => {
    const cache = createCache(options);
    cache.compat = true;
    const prevInsert = cache.insert;
    let inserted = [];
    cache.insert = (...args) => {
      const serialized = args[1];
      if (cache.inserted[serialized.name] === undefined) {
        inserted.push(serialized.name);
      }
      return prevInsert(...args);
    };
    const flush = () => {
      const prevInserted = inserted;
      inserted = [];
      return prevInserted;
    };
    return { cache, flush };
  });

  useServerInsertedHTML(() => {
    const names = flush();
    if (names.length === 0) {
      return null;
    }
    let styles = '';
    for (const name of names) {
      styles += cache.inserted[name];
    }
    return (
      <style
        key={cache.key}
        data-emotion={`${cache.key} ${names.join(' ')}`}
        dangerouslySetInnerHTML={{
          __html: styles,
        }}
      />
    );
  });

  return (
    <CacheProvider value={cache}>
      <ThemeProvider theme={theme}>
        <CssBaseline /> // BY REMOVING THE CssBaseline COMPONENT THE PROBLEM GOES AWAY
        {children}
      </ThemeProvider>
    </CacheProvider>
  );
}

/app/test/page.js

import { dehydrate } from "@tanstack/query-core";
import getQueryClient from "../utils/getQueryClient";
import Hydrate from "../utils/hydrate.client";
import ListUsers from "./list";

async function getUsers() {
  const res = await fetch("https://jsonplaceholder.typicode.com/users");
  const users = await res.json()
  return users;
}

export default async function Hydation() {
  const queryClient = getQueryClient();
  await queryClient.prefetchQuery(["hydrate-users"], getUsers);
  const dehydratedState = dehydrate(queryClient);

  return (
    <Hydrate state={dehydratedState}>
      <ListUsers />
    </Hydrate>
  );
}
export const runtime = 'edge'; // BY REMOVING THE RUNTIME EDGE THE PROBLEM GOES AWAY

The server log on a request to /test would be

- wait compiling...
- event compiled client and server successfully in 510 ms (2881 modules)
- error TypeError: Cannot read properties of undefined (reading 'fontWeightBold')

Itโ€™s worth noting that the error doesnโ€™t prevent the page to render on the client but it breaks the ssr

My deps

 "@emotion/cache": "^11.10.5",
    "@emotion/react": "^11.10.6",
    "@emotion/server": "^11.10.0",
    "@emotion/styled": "^11.10.6",
    "@mui/icons-material": "^5.11.11",
    "@mui/material": "^5.11.13",
    "@mui/styles": "^5.8.3",
    "@mui/system": "^5.11.12",
    "next": "^13.4.2",

@BartoszJanowski no unfortunately this is still an issue for me and itโ€™s blocking me as it breaks the SSR

@mj12albert do you know if is there any plan of coming with a fix for this?