emotion icon indicating copy to clipboard operation
emotion copied to clipboard

Hydration error using Next.js 15 and MUI 6 when using Turbopack builder

Open kangalio opened this issue 10 months ago β€’ 25 comments

Current behavior:

Using Next.js 15 and MUI 6, an Emotion-related hydration error appears when the page is SSR-rendered. After reading https://github.com/chakra-ui/chakra-ui/issues/8970, I figured out, this only happens using the new --turbopack builder from Next.js (which has been the new default for some time)

To reproduce:

  1. Clone https://github.com/kangalio/emotion-hydration-error-reproducible
  2. Run npm install and then npx next dev --turbopack
  3. Open the website (i.e. localhost:3000)
  4. Observe:
    • Image
    • Image

Expected behavior:

I expect no error to be thrown.

Environment information:

  • @emotion/babel-plugin: 11.13.5
  • @emotion/cache: 11.14.0
  • @emotion/hash: 0.9.2
  • @emotion/is-prop-valid: 1.3.1
  • @emotion/memoize: 0.9.0
  • @emotion/react: 11.14.0
  • @emotion/serialize: 1.3.3
  • @emotion/sheet: 1.4.0
  • @emotion/styled: 11.14.0
  • @emotion/unitless: 0.10.0
  • @emotion/use-insertion-effect-with-fallbacks: 1.2.0
  • @emotion/utils: 1.4.2
  • @emotion/weak-memoize: 0.4.0
  • react: 19.0.0
  • react-dom: 19.0.0
  • react-is: 16.13.1
  • react-transition-group: 4.4.5

(Taken from the linked reproducible repo's package-lock.json)

Potentially related issues:

  • https://github.com/emotion-js/emotion/issues/3222

kangalio avatar Jan 22 '25 23:01 kangalio

I have the same issue when running with --turbopack:

Unhandled Runtime Error

Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used

- A server/client branch `if (typeof window !== 'undefined')`.
- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.
- Date formatting in a user's locale which doesn't match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.

It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.

See more info here: https://nextjs.org/docs/messages/react-hydration-error


 ...
  <OuterLayoutRouter parallelRouterKey="children" segmentPath={[...]} template={<RenderFromTemplateContext>}>
    <RenderFromTemplateContext>
      <ScrollAndFocusHandler segmentPath={[...]}>
        <InnerScrollAndFocusHandler segmentPath={[...]} focusAndScrollRef={{apply:false, ...}}>
          <ErrorBoundary errorComponent={undefined} errorStyles={undefined} errorScripts={undefined}>
            <LoadingBoundary loading={null}>
              <HTTPAccessFallbackBoundary notFound={undefined} forbidden={undefined} unauthorized={undefined}>
                <RedirectBoundary>
                  <RedirectErrorBoundary router={{...}}>
                    <InnerLayoutRouter parallelRouterKey="children" url="/dashboard..." tree={[...]} childNodes={Map} ...>
                      <script>
                        <script>
                          <script>
                            <script>
                              <script>
                                <Layout>
                                  <Box sx={{display:"flex"}}>
                                    <Styled(div) as="div" ref={null} className="MuiBox-root" theme={{...}} sx={{display:"flex"}}>
                                      <Insertion>
+                                        <div className="MuiBox-root css-k008qs">
-                                        <style data-emotion="css-global ghzezc" data-s="">

karimodm avatar Jan 29 '25 14:01 karimodm

I am also seeing this error with:

"@emotion/react": "11.14.0", "@emotion/styled": "11.14.0", "@heroicons/react": "2.2.0", "@mui/icons-material": "6.4.2", "@mui/material": "6.4.2",

Image

OliverHolden avatar Feb 02 '25 22:02 OliverHolden

Greetings!

I have the same problem, but with a slightly different configuration (NextJS 15 / Chakra UI 3)...what I have not done - nothing helps, but without --turbopack - the error disappears(

deluxart avatar Feb 10 '25 09:02 deluxart

I am also having the same issue!

"@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", "@mui/icons-material": "^6.4.6", "@mui/material": "^6.1.10", "next": "15.1.0", "next-auth": "^4.24.11", "react": "^19.0.0", "react-dom": "^19.0.0",

node version 23.5.0

Image

whoisasey avatar Mar 06 '25 19:03 whoisasey

I was seeing this error too, and solved it.

First, error reproduction steps (skip several by cloning this at the linked-to point in history): npx create-next app (installed v15.2.2, the latest) Project name: emotion3308 TypeScript, ESLint, Tailwind, src/ dir, app router, Turbopack: Yes Customize import alias: No cd emotion3308 npm i @mui/material @emotion/react @emotion/styled In src/app/page.tsx, add import Button from '@mui/material/Button'; In the same file just before the first <Image add:

        {/* You can get rid of both the error (and the button) by moving the contents of 
        the next line to the end of the line below it.
        */}
        <Button>Problem Causer</Button>

Or you can skip all that and just clone this at the linked-to point in the commit history.
Then npm run dev (aka next dev --turbopack) and the issue is observed. Note that if you make changes and rely on the soft reload, ANY change you make will appear to fix the issue. Be sure to do an F5 full page reload to test and see if you see the error.

I found this issue from last summer in which <Typography> was being rendered as <span> on the server and <p> on the client which leads to a mismatch. However, in that case, updating to the latest canary version of Next worked, and that has since been released but the problem is still being observed. I also found this still-open issue from around the same time frame. Per this comment, wrapping with an MUI <Box> fixes the issue, but that does not seem like an ideal solution.

Per this older Reddit post, following the MUI instructions for Next.js integration did much better. Namely, stop the server, npm i @mui/material-nextjs @emotion/cache (the latter just makes the dependency more explicit), then modify src/app/layout.tsx to import { AppRouterCacheProvider } from '@mui/material-nextjs/v15-appRouter'; at the top and wrap the {props.children} line in <AppRouterCacheProvider>… </AppRouterCacheProvider>. There are some other useful instructions there. I would propose closing this Issue.

boiseiben avatar Mar 11 '25 14:03 boiseiben

Also happens with MUI 7, and only with turbopack.

lucach avatar Mar 31 '25 08:03 lucach

@lucach Are you following the MUI instructions for Next.js integration?

boiseiben avatar Apr 01 '25 20:04 boiseiben

@lucach Are you following the MUI instructions for Next.js integration?

I am.

I'm already using the *CacheProvider wrapper component. I'm still using the Pages router, so the wrapper is AppCacheProvider, from @mui/material-nextjs/v15-pagesRouter.

lucach avatar Apr 02 '25 12:04 lucach

@lucach Are you following the MUI instructions for Next.js integration?

This fixed it for me πŸ‘

karimodm avatar Apr 02 '25 13:04 karimodm

@lucach Are you following the MUI instructions for Next.js integration?

I am.

I'm already using the *CacheProvider wrapper component. I'm still using the Pages router, so the wrapper is AppCacheProvider, from @mui/material-nextjs/v15-pagesRouter.

To be more precise: the page renders correctly. The hydration error is only shown in the console. Classes only differ by their prefix:

                      <div
+                       className="MuiBox-root mui-wao269"
-                       className="MuiBox-root css-wao269"
                      >

lucach avatar Apr 03 '25 13:04 lucach

@lucach Are you following the MUI instructions for Next.js integration?

This fixed it for me πŸ‘

It does work but not in the turbopack mode. Are you seeing this error when running next --turbopack?

barthicus avatar Apr 16 '25 07:04 barthicus

@barthicus No, the problem is in normal mode without turbopack. As @lucach pointed out, the project is on Pages router.

kendrive avatar May 05 '25 10:05 kendrive

I have the same problem.

smartdeveler avatar May 16 '25 18:05 smartdeveler

We have the same problem using the Pages router, with or without turbopack. The problem does not occur if using the App router.

JB-Scott avatar May 19 '25 00:05 JB-Scott

I'm using the App router and the problem occurs with turbopack.

On Mon, May 19, 2025, 03:41 JB-Scott @.***> wrote:

JB-Scott left a comment (emotion-js/emotion#3308) https://github.com/emotion-js/emotion/issues/3308#issuecomment-2889296880

We have the same problem using the Pages router, with or without turbopack. The problem does not occur if using the App router.

β€” Reply to this email directly, view it on GitHub https://github.com/emotion-js/emotion/issues/3308#issuecomment-2889296880, or unsubscribe https://github.com/notifications/unsubscribe-auth/AL3VALBB6EMHENJBAQ4XG4T27EOUHAVCNFSM6AAAAABVWBT26WVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDQOBZGI4TMOBYGA . You are receiving this because you commented.Message ID: @.***>

smartdeveler avatar May 19 '25 00:05 smartdeveler

I'm using the App router and the problem occurs with turbopack.

@smartdeveler Are you following the MUI instructions for Next.js integration? That fixed it for me using the app router with turbopack.

boiseiben avatar Jun 19 '25 13:06 boiseiben

Yes. I following that instruction but not fixed with turbopack.

smartdeveler avatar Jun 21 '25 09:06 smartdeveler

We are also seeing similar issues. Any guidance so far from MUI team?

oswaldoacauan avatar Jul 04 '25 15:07 oswaldoacauan

I updated some of our dependencies, now we are using mui/material 7.2.0 and @emotion/styled 11.14.1 and it seems to solve the issue. I did a POC with this dependencies and it worked fine for me:

"@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", "@mui/icons-material": "^7.2.0", "@mui/material": "^7.2.0", "next": "15.3.5", "react": "^19.0.0", "react-dom": "^19.0.0"

Im using App Router with turbopack.

Hope it helps somebody someday.

JorgeRodr avatar Jul 07 '25 15:07 JorgeRodr

I updated some of our dependencies, now we are using mui/material 7.2.0 and @emotion/styled 11.14.1 and it seems to solve the issue. I did a POC with this dependencies and it worked fine for me:

"@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", "@mui/icons-material": "^7.2.0", "@mui/material": "^7.2.0", "next": "15.3.5", "react": "^19.0.0", "react-dom": "^19.0.0"

Im using App Router with turbopack.

Hope it helps somebody someday.

This worked for me with update : "@mui/icons-material": "^7.2.0", "next": "15.3.5",

smartdeveler avatar Jul 09 '25 09:07 smartdeveler

Same error with ChakraUI, Next, and Turbopack:

            <RootLayout>
              <html lang="en" suppressHydrationWarning={true}>
                <body className="geist_a715...">
                  <Provider>
                    <ChakraProvider value={{$$chakra:true, ...}}>
                      <EmotionGlobal>
                      <EmotionGlobal>
                      <ColorModeProvider>
                        <J attribute="class" disableTransitionOnChange={true}>
                          <V attribute="class" disableTransitionOnChange={true}>
+                           <script
+                             suppressHydrationWarning={true}
+                             nonce=""
+                             dangerouslySetInnerHTML={{__html:"((e, i, s,..."}}
+                           >
-                           <style data-emotion="css-global ad1llf" data-s="">

jcubic avatar Sep 24 '25 08:09 jcubic

In my case I got such errors because I'm using MaterialUI and I was using StyledEngineProvider (@mui/material) as a child of AppRouterCacheProvider (@mui/material-nextjs/v13-appRouter). Making StyledEngineProvider a parent of AppRouterCacheProvider solved most errors about different css.

The remaining css hydration issues was because I was using emotion CacheProvider (@emotion/react, along with createCache from @emotion/cache) and somehow it was conflicting with MaterialUI cache, that probably uses the emotion provider under the hood, so I just removed the emotion CacheProvider and kept just AppRouterCacheProvider.

lucasbasquerotto avatar Sep 24 '25 11:09 lucasbasquerotto

Confirmed: Issue persists with Next.js 15.5.4 + Turbopack

Environment:

  • Next.js: 15.5.4
  • Turbopack: --turbopack flag
  • Emotion: Latest version
  • App Router: Yes

Reproduction: The hydration error only occurs when using --turbopack. Running the same code with the default webpack bundler works fine without any hydration warnings.

Current Workaround: For developers experiencing this issue, the only reliable workaround is to disable Turbopack during development:

# Instead of
npm run dev --turbopack

# Use
npm run dev

l7aromeo avatar Sep 27 '25 09:09 l7aromeo

I was able to fix the issue by removing <StyledEngineProvider injectFirst>. When using <AppRouterCacheProvider>, you don’t need to wrap it manually because it already handles style injection automatically.

Details: In my app, <StyledEngineProvider> was nested inside <AppRouterCacheProvider>, which caused style injection conflicts and the insertBefore error. Removing it solved the problem.

For best results, make sure to follow the official MUI documentation:

Next.js integration

TailwindCSS integration

If it still doesn’t work, you can try this workaround:

import { createCache } from "@emotion/react";

createCache({ key: "mui", prepend: true });

return (
  <html>
    <body>
      <AppRouterCacheProvider>
        <MuiThemeProvider theme={yourCurrentActiveTheme}>
          <CssBaseline />
          {children}
        </MuiThemeProvider>
      </AppRouterCacheProvider>
    </body>
  </html>
);

Patel-Samir avatar Sep 27 '25 18:09 Patel-Samir

So at this point it seams that the problem has a solution for app router but not for pages router. I made this repro repo : https://github.com/Mattgic/next-mui-turbopack-bug with an example page on app router and another on pages router. I only have an error with pages router, and only if I run Next with Turbopack.

I also have no errors if I try to add custom emotion css (with css prop) on a div with pages router + Turbopack On this repo I use Next v15 because @mui/material-nextjs is still not compatible with Next v16.

So the problem seems to be Turbopack + MUI + Pages router

I guess the problem is more on the Turbopack side than on MUI ?

Mattgic avatar Oct 31 '25 09:10 Mattgic