question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ServerStyleSheets does not propagate props to StylesProvider component.

See original GitHub issue
  • The issue is present in the latest release.
  • I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 😯

I’m trying to add Material-UI to my application in Next.js. I started from checking out example that you have in your official docs: https://github.com/mui-org/material-ui/tree/master/examples/nextjs I wanted to change injection order of CSS - in my application, components will be styled with SCSS files so I wanted those stylesheets to override jss stylesheets. According to documentation passing an object to ServerStyleSheets spreads that object to StylesProvider component: https://github.com/mui-org/material-ui/tree/master/examples/nextjs so I passed injectFirst prop, but it doesn’t get passed to StylesProvider. Other props, like disableGeneration do get passed and they work, but injectFirst doesn’t.

Expected Behavior 🤔

Passing injectFirst prop to ServerStyleSheets should pass it to StylesProvider which should result in changed injection order of CSS files.

Steps to Reproduce 🕹

Link to codesandbox: https://codesandbox.io/s/github/mui-org/material-ui/tree/master/examples/nextjs

Steps:

  1. Add object { injectFirst: true } as parameter to ServerStylesSheets() in _document.js
  2. Check order of stylesheets in <head> tag

Context 🔦

It’s impossible to have both SSR and changed injection order - injectFirst prop doesn’t work, so Material-UI stylesheets always get injected last, thus overriding all my custom SCSS styles.

Your Environment 🌎

Tech Version
Material-UI v4.9.14
React 16.13.1
Browser Chrome
TypeScript x
etc. Next.js @ 9.4.0

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:11 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
martin8877commented, Mar 10, 2021

Thank you. Problem solved. Nextjs always inserts the content of styles prop at the end of <head> element, but global / module css at the start. So I need to pass my own prop and render style tag.

Working example:

import Document, { Html, Head, Main, NextScript } from 'next/document';
import { ServerStyleSheets } from '@material-ui/core/styles';
import theme from 'theme';

export default class MyDocument extends Document {
    render() {       
        return (
            <Html lang="en">
                <Head>
                    <meta name="theme-color" content={theme.palette.primary.main} />
                    {this.props.materialStyle}
                </Head>
                <body>
                    <Main />
                    <NextScript />
                </body>
            </Html>
        );
    }
}

MyDocument.getInitialProps = async (ctx) => {
    const sheets = new ServerStyleSheets();
    const originalRenderPage = ctx.renderPage;

    ctx.renderPage = () =>
        originalRenderPage({
            enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
        });

    const initialProps = await Document.getInitialProps(ctx);

    return {
        ...initialProps,
        materialStyle: sheets.getStyleElement()
    };
};
1reaction
martin8877commented, Mar 10, 2021

I’m talking about changing styles order at build level (SSR). <StylesProvider injectFirst/> doesn’t work with SSR (I understand why). And I haven’t found a way to change styles injection order in _document.js at nextjs. I can’t hook into nextjs rendering. Only enhance app component with something like this:

MyDocument.getInitialProps = async (ctx) => {
    const sheets = new ServerStyleSheets();
    const originalRenderPage = ctx.renderPage;
    ctx.renderPage = () =>
        originalRenderPage({
            enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
      });
    const initialProps = await Document.getInitialProps(ctx);
    return {
        ...initialProps,
        styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
    };
};

But this cause FOUC (it takes a little bit of time until JS loads and removes #jss-server-side - hence the linked workaround):

    React.useEffect(() => {
        // Remove the server-side injected CSS.
        const jssStyles = document.querySelector('#jss-server-side');
        if (jssStyles) {
            jssStyles.parentElement.removeChild(jssStyles);
        }
    }, []);

I dont’ want to use !import in my css files, that’s ugly.

Or am I missing something?

Read more comments on GitHub >

github_iconTop Results From Across the Web

ServerStyleSheets does not propagate props to ... - GitHub
According to documentation passing an object to ServerStyleSheets spreads that object to StylesProvider component: https://github.com/mui-org/ ...
Read more >
Styles API - MUI System
The instantiation accepts an options object as a first argument. options (object [optional]): The options are spread as props to the StylesProvider component....
Read more >
Propagate style props to React children and apply them to a ...
Since you are wanting to only pass the style (now listStyles and currentStyles) and the className I chose to assign them to a...
Read more >
@mui/styles | Yarn - Package Manager
You can leverage our styling solution, even if you are not using our components. Installation. Install the package in your project directory with:...
Read more >
Material Ui <Stylesprovider Injectfirst> Causes Style Crash ...
Now you can override Material-UI's styles. import * as React from 'react'; ... ServerStyleSheets does not propagate props to StylesProvider component.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found