Using Material-UI with @emotion/cache in SSR results in consistently empty cache

After transitioning my React SSR from pure @emotion to material-ui 5.0, I encountered an issue where the styles no longer get extracted. The ID extraction in createExtractCriticalToChunks seems to be functioning correctly, but the cache.inserted object from emotion is always empty. Can anyone point out what I might be doing wrong here?

 "@emotion/babel-plugin": "^11.3.0",
 "@emotion/cache": "^11.6.0",
 "@emotion/core": "11.0.0",
 "@emotion/css": "^11.5.0",
 "@emotion/react": "^11.6.0",
 "@emotion/server": "^11.4.0",
 "@emotion/styled": "^11.6.0",
 "@mui/icons-material": "5.0.0",
 "@mui/lab": "5.0.0-alpha.47",
 "@mui/material": "5.0.0",
 "@mui/styles": "5.0.0",
 "@mui/utils": "5.0.0",
 "@mui/x-data-grid": "5.0.0-beta.1",

HTML:

<style data-emotion="css-global 1vs7qi2"> (styles continue...)

Extracted ID's:

{
  global: true,
  khurd4: true,
  '1ure1x2': true,
   (ID's continue...)
}

Cache:

{
  key: 'css',
  sheet: e {
    (cache details...)
  },
  nonce: undefined,
  inserted: {},
  registered: {},
  insert: [Function: o],
  compat: true
}

Cache Setup SSR:

(SSR setup code snippet...)

ServerApp.js

(<ServerApp component structure...)

MUI SSR: Link to MUI Server Rendering Guide

Answer №1

After some investigation, I pinpointed the issue and successfully resolved it.

It appears that during my transition from Material 4 to MUI 5, one of the codemods included wrapping my code in a <StyledEngineProvider> for styled components server-side rendering. This provider also created an emotionCache with key:'css', causing conflicts with the custom emotionCache I had implemented. By removing the <StyledEngineProvider> wrapper, the styles returned from server-side rendering as expected.

Answer №2

Update: The documentation lacks clarity on how the cache functions, but after investigation, I discovered it was not a bug. I managed to resolve my problem by removing a <StyledEngineProvider> that was wrapping my code after upgrading from mui4 to mui5.


I am encountering a similar issue. Upon inspecting the source code in emotion, it appears to be a bug as the matched keys are not being placed into the returned object correctly.

After matching the keys, the code should iterate through them. However, it erroneously utilizes a forEach loop with the keys from cache.inserted. Unless you manage the matching and insertion yourself, cache.inserted will remain empty.

Instead of:

Object.keys(cache.inserted).forEach(id => {

it should read:

Object.keys(ids).forEach(id => {

You can take a look at the complete code here:

I plan to raise an issue on their repository.

Answer №3

Response from @emotion team (Mateusz):

In another context - I suggest avoiding `css` as your key identifier. This is the default and may clash with other styles controlled by Emotion. Even our error message indicates that the key should be distinct from `css`: https://github.com/emotion-js/emotion/blob/2bac69b6c058d007cfc190e94490c0cb225ca40c/packages/cache/src/index.js#L49-L54

Regarding your problem - I recommend double-checking that you are not utilizing `@emotion/core` anywhere and that there is only one instance of `@emotion/react` in your node_modules.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The Socket.io Chat application is indicating a memory leak with the EventEmitter, detecting 11 listeners that have been added. To resolve this issue

My private chat application is built using socket.io, node.js, and MySQL. However, I encountered an error when trying to use socket.on('example', function(data){...});. The error code thrown is related to a possible EventEmitter memory leak with ...

Obtain text content using JQuery and AJAX rather than retrieving the value

I am struggling with a dynamic table that needs to perform calculations before submitting, requiring the presence of values. However, I want to submit the text from the options instead of the values. Despite trying various approaches, none of them seem to ...

Can someone explain the process of adding a JavaScript state variable from one React component so that it can be utilized in other components?

In my Home.js component, I handle user sign up to the API and login. After receiving the token from the authorization header in the response, I save it in the state variable 'token'. This token is crucial for accessing the API in other component ...

Error TS2322: The function expecting a type of 'FormEventHandler<HTMLFormElement>' cannot be assigned the type '(data: TicketFullDTO) => Promise<void>'

I am currently working on creating an edit form to modify data from a database based on its ID. Here is my approach: import React, {FormEvent, useEffect, useState} from "react"; import TextField from "@material-ui/core/TextField" ...

Is it possible to extract elements from a single list and insert them onto various pages?

Currently, I am retrieving items from a list using an ajax call. After constructing the HTML content, I insert these items onto a page. Now, I want to extract the same items and display them on another page with a different style. Is there a method to conn ...

What is the speed difference between calling functions from require's cache in Node.js and functions in the global scope?

Let's imagine a scenario where we have two files: external.js and main.js. // external.js //create a print function that is accessible globally module.exports.print = function(text) { console.log(text) } Now let's take a look at main.js: ...

ReactJS form example: utilizing two separate submit buttons to perform distinct actions on the same form

I need to implement two submit buttons in my form. Both buttons should utilize the same inputs and form validation, but trigger different actions. export default function FormWithTwoSubmits() { function handleSubmitTask1(){ } function handleSub ...

The POST variable consistently remains void

The approach I am using to handle the data sent with jquery.ajax involves sending an empty string by default. Whenever there is a change, I monitor the input for changes and resend the data. Everything seems to work fine in the console, but in PHP, $this-& ...

Leveraging the power of async to streamline the serialization of operations with numerous layers of callbacks in Node

I'm relatively new to working with node.js and I'm encountering difficulties in understanding callback functions. The issue arises when I need to execute a series of complex operations that involve a lot of code divided into modules with numerous ...

The wrapAll() method can be used to wrap list items within two columns

I am looking to group multiple li elements within two div containers by using jQuery's wrapAll method. The challenge lies in the fact that these items are rendered within a single <ul> element via a CMS. Here is the current setup: <ul> ...

When an input is disabled in "react-hook-form", it may return undefined

Within my React application, there exists a form containing various input fields. I have enclosed these fields using FormProvider imported from react-hook-form and utilized register within each field. import { useForm, FormProvider, useFormContext } from & ...

Pressing the enter key within Material UI Autocomplete will allow you to quickly create new

Wouldn't it be great if Autocomplete in material ui could do this: wertarbyte Imagine being able to insert text (string) without the need for a list of elements to select from. This means that the noOptions message shouldn't appear, and instead ...

Shopping Directive Coverage Discrepancy

In my application, there is a shop item directive that includes a price attribute. When a user interacts with the directive, the total cost (a variable stored in the main controller) should be updated by the price of the item that was clicked. Unfortunate ...

ESLint encountered an error while attempting to load the configuration "next/babel" for extension

Every time I try to generate a build of my Next.js app by running "npm run build," I keep encountering this error. Check out the error I'm getting while running npm run build here. Also, take a look at my .eslintrc.json file here and my .babelrc file ...

Downloading a file utilizing Selenium through the window.open method

I am having trouble extracting data from a webpage that triggers a new window to open when a link is clicked, resulting in an immediate download of a csv file. The URL format is a challenge as it involves complex javascript functions called via the onClick ...

The hit detection algorithm seems to be malfunctioning, and the reason behind it is unclear. (Using Javascript/Processing

I am a beginner in game programming and programming in general. In the past, I have created a clone of "Flappy Bird" and some other games using the hit detection algorithm from the Mozilla Developer Network here. Currently, I am facing an issue while tryi ...

Preventing Bull Queue from automatically re-starting jobs upon server restart

Currently, I am utilizing the bull queue system for processing jobs. Imagine a scenario where a job is in progress with an active status and I restart my development server. Upon restarting the worker script, the job remains in the active state within the ...

Executing Javascript requests on a php server hosted on the web

I'm facing a major issue in my application. I have an app that interacts with a PHP webservice and retrieves data upon button press. However, the service is unresponsive, and I'm struggling to identify the root cause. My intention is to send &ap ...

"AngularJS makes it easy for the logged-in user's information to be accessible and available across

I need to ensure that user information is accessible across all views after logging in. How can I adjust the code to be able to retrieve the pseudonym from another view? Could you provide an example as well? Below is my login controller: app.controller ...

What is the proper way to utilize the setState() function in ReactJS?

I am new to the world of ReactJS and I have been exploring the concepts of state and setState(). While trying to implement a name change using setState(), I found myself wondering where exactly in my code should I invoke the setState() method: Should I c ...