Gatsby: losing style on page reload

Created on 7 Feb 2020  路  17Comments  路  Source: gatsbyjs/gatsby

Description

After gatsby build the app works fine until I reload the page. It then loose styles coming from material-ui in a specific component.

The app works fine:

  • in development
  • in production, for as long as no page reload is hit

No error message is thrown, either in the build process or when the problem actually happens, ie, page reload.

Steps to reproduce

  • run gatsby build
  • run gatsby serve or deploy to Netlify
  • hit page reload in the browser

You can see it for yourself. The app is available on Netlify at https://musing-davinci-538143.netlify.com/

Just load the app, scroll down to the footer and then reload the page.

After that, if you clear the browser cache and reload the app it will work correctly again. Till a new page reload.

Expected result

Page reload should not impact the app styles.

Actual result

As explained.

Environment

System:
OS: macOS 10.15.3
CPU: (4) x64 Intel(R) Core(TM) i5-4570S CPU @ 2.90GHz
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 10.16.3 - /usr/local/bin/node
npm: 6.9.0 - /usr/local/bin/npm
Languages:
Python: 2.7.16 - /usr/bin/python
Browsers:
Chrome: 80.0.3987.87
Firefox: 65.0.1
Safari: 13.0.5
npmPackages:
gatsby: ^2.18.2 => 2.18.2
gatsby-cli: ^2.6.4 => 2.6.4
gatsby-image: ^2.2.33 => 2.2.33
gatsby-link: ^2.2.24 => 2.2.24
gatsby-plugin-create-client-paths: ^2.1.17 => 2.1.17
gatsby-plugin-eslint: ^2.0.8 => 2.0.8
gatsby-plugin-manifest: ^2.2.29 => 2.2.29
gatsby-plugin-material-ui: ^2.1.6 => 2.1.6
gatsby-plugin-offline: ^3.0.22 => 3.0.22
gatsby-plugin-react-helmet: ^3.1.15 => 3.1.15
gatsby-plugin-sass: ^2.1.23 => 2.1.23
gatsby-plugin-sharp: ^2.3.2 => 2.3.2
gatsby-source-filesystem: ^2.1.38 => 2.1.38
gatsby-source-graphql: ^2.1.24 => 2.1.24
gatsby-transformer-sharp: ^2.3.5 => 2.3.5

This is the component where the error appears.

/src/components/footerCategoryLinks.js

  import React from 'react';
 import { withStyles } from '@material-ui/core/styles';
 import { MenuList, MenuItem } from '@material-ui/core';
 import { Link } from 'gatsby';
 import Divider from '@material-ui/core/Divider';
import PropTypes from 'prop-types';

const styles = (theme) => ({
allCats: {
    display: 'grid',
    gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 180px))',
    padding: '10px',
    justifyContent: 'space-evenly',
    [theme.breakpoints.down('xs')]: {
        display: 'block',
        margin: '0 auto',
        maxWidth: '280px',
    },
    '& a': {
        textDecoration: 'none',
    },
    '& li': {
        color: '#2d5074',
        paddingTop: '4px',
        paddingBottom: '4px',
    },
},
type: {
    textTransform: 'uppercase',
    fontWeight: '700',
    fontSize: '1rem',
},
cat: {
    '& li': {
        textTransform: 'uppercase',
        fontWeight: '600',
        fontSize: '.8rem',
    },
},
subcat: {
    '& li': {
        marginLeft: '10px',
        fontSize: '0.8rem',
        textTransform: 'capitalize',
    },
},
empty: {
    visibility: 'hidden',
},
});

const CategoryLinks = (props) => {
const { categories, classes } = props;
const main = ['objects', 'services'];
const output = [];
let rows = [];
let ctRows = 0;
const catLength = categories.length;
main.forEach((type) => {
    rows.push(<MenuItem className={classes.type} key={type}>{type}</MenuItem>);
    ctRows++;
    categories.forEach((row, catIndex) => {
        if (row.root && row.root.title === type &&
            row.parent.title === type) {
            let parentTitle = row.title.replace(' ', '-');
            parentTitle = parentTitle.replace(',', '');
            if (ctRows > 1 && ctRows < 6) {
                rows.push(
                    <Divider
                        key={`${row.title}${Math.floor(
                            Math.random() * 100000,
                        )}`}
                    />,
                );
            }
            if (ctRows === 0) {
                rows.push(
                    <MenuItem
                        key={Math.floor(Math.random() * 100000)}
                        className={classes.empty}
                    >
                        empty
                    </MenuItem>,
                );
            }
            rows.push(
                <Link
                    className={classes.cat}
                    key={row.id}
                    to={`/search/${type}/${parentTitle}`}
                >
                    <MenuItem key={row.id}>{row.title}</MenuItem>
                </Link>,
            );
            ctRows++;
            categories.forEach((row1) => {
                if (row1.parent && row1.parent.title === row.title) {
                    rows.push(
                        <Link
                            className={classes.subcat}
                            key={row1.id}
                            to={`/search/${type}/${parentTitle}/${row1.title.replace(' ', '-')}`}
                        >
                            <MenuItem key={row1.id}>{row1.title}</MenuItem>
                        </Link>,
                    );
                    ctRows++;
                }
            });
        }
        if (ctRows > 5 || catIndex === catLength - 1) {
            output.push(<div key={Math.floor(Math.random() * 100000)}>{rows}</div>);
            rows = [];
            ctRows = 0;
        }
    });
});
return (
    <div>
        <MenuList className={classes.allCats}>
            {output.map((item) => {
                return item;
            })}
        </MenuList>
    </div>
);
};

CategoryLinks.propTypes = {
    categories: PropTypes.array.isRequired,
    classes: PropTypes.object.isRequired,
};

export default withStyles(styles)(CategoryLinks);
stale? question or discussion

Most helpful comment

Not stale. Ongoing issue.

All 17 comments

Hello @BernardA !

Do you have a file gatsby-browser and gatsby-ssr?

Here they are ( they look exactly the same )

 import React from 'react';
 import { Provider } from 'react-redux';
 import store from './src/store/reduxWrapper';
 import Layout from './src/components/layout';

 export const wrapRootElement = ({ element }) => <Provider store={store}>{element}</Provider>;

  export const wrapPageElement = ({ element, props }) => {
      return <Layout {...props}>{element}</Layout>;
};

The offending component (/src/components/footerCategoryLinks.js ) is part of the <Footer /> component included in the <Layout /> component below, which wraps all pages as per gatsby-browser and gatsby-ssr.

   import React from 'react';
import PropTypes from 'prop-types';
 import { useStaticQuery, graphql } from 'gatsby';
 import CssBaseline from '@material-ui/core/CssBaseline'; // reset CSS
 import Header from './header';
 import Footer from './footer';
mport SessionHander from './sessionHandler';
import OnlineHandler from './onlineHandler';
import '../styles/layout.css'; // global CSS
import styles from '../styles/layout.module.scss';

const Layout = ({ children, location }) => {
const { site } = useStaticQuery(
    graphql`
        query {
            site {
                siteMetadata {
                    title
                }
            }
        }
    `,
);
return (
    <div className={styles.container}>
        <CssBaseline />
        <div>
            <Header
                siteTitle={site.siteMetadata.title}
                location={location}
            />
            <SessionHander location={location} />
            <OnlineHandler location={location} />
            <>{children}</>
        </div>
        <Footer />
    </div>
);
};


Layout.propTypes = {
site: PropTypes.shape({
    siteMetadata: PropTypes.shape({
        title: PropTypes.string.isRequired,
    }).isRequired,
}),
children: PropTypes.node.isRequired,
location: PropTypes.object.isRequired,
};

export default Layout;

Certainly looks like styles are breaking after JavaScript is loaded (disabling it fixes the issue)

Are you using the right versions of material-ui and gatsby-plugin-material-ui?The README at https://github.com/hupe1980/gatsby-plugin-material-ui says that it only works with v4

I realized I did not make clear the fact that I am using react-material-ui extensively in this app. So, many of my components are using it but, for some reason, only the one above is breaking on reload.
I am not sure what is specific about that component that is causing the error.
For information, here are the versions of the packages you mentioned:

  "@material-ui/core": "^4.7.0",
   "@material-ui/icons": "^4.5.1",
   "@material-ui/lab": "^4.0.0-alpha.38",
   "@material-ui/styles": "^4.6.0",
  "gatsby-plugin-material-ui": "^2.1.6",

@BernardA That would suggest that the component in question possibly doesn't support SSR or is somehow styled differently on SSR and then on the client leading to a hydration mismatch and therefore breaking styles when JavaScript loads?

A minimal reproduction of the codebase should help. I would also suggest opening an issue in the material-ui repository since this doesn't seem to be strictly Gatsby related

As said, I could not find anything specific to this component that could explain the different behavior and after all it is a rather plain component.
Also, as shown, gatsby-browser and gatsby-ssr are exactly the same. So no reasons from the config perspective either.
The code is available at https://github.com/BernardA/quiamo ( I may need to withdraw it momentarily ).

Hiya!

This issue has gone quiet. Spooky quiet. 馃懟

We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 馃挭馃挏

Not stale. Ongoing issue.

I have a similar problem but it is after reloading page in light mode.
Source code
Demo of development code
Demo of production code

I was curious to see if Reactjs had the same the problem so I reproduced my problem in React.

Source in React
Demo of development code
Demo of production code

It is working fine in React but not in Gatsby. I think the problem might lies in Gatsby build process. Can someone please update and change the status of this issue?

@chivongv . I agree with you concerning the status. This should be a bug, not question/discussion. It's up to the moderators though.

Concerning the issue as such, I worked around it by removing react-material-ui's withStyles and added back the same styles using scss like so:

import styles from '../styles/footerCategory.module.scss';

Again, this is a work around and as I stated above, I use withStyles extensively all over my app. Only this specific instance is generating an issue. Not sure what's specific about it.

I'm also having the same issue with losing styling on reload, but I'm using Foundation6 with reach-router. Seems this issue is with the gatsby build process.

I found a fix from this article: https://joshwcomeau.com/react/the-perils-of-rehydration/

Hiya!

This issue has gone quiet. Spooky quiet. 馃懟

We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 馃挭馃挏

Hey again!

It鈥檚 been 30 days since anything happened on this issue, so our friendly neighborhood robot (that鈥檚 me!) is going to close it.
Please keep in mind that I鈥檓 only a robot, so if I鈥檝e closed this issue in error, I鈥檓 HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks again for being part of the Gatsby community! 馃挭馃挏

I'm still facing this issue on many of my projects. If anyone found a solution please help.

@hayyaun I solved this by using @emotion/styled and theme-ui. Hope you will find it helpful

hi, I was searching for this issue, thanks for replying.
I found out that gatsby-plugin-minify was the reason all my styles flickered for some seconds.
And I still don't know the reason. But in my case removing it solved my problem.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dustinhorton picture dustinhorton  路  3Comments

brandonmp picture brandonmp  路  3Comments

KyleAMathews picture KyleAMathews  路  3Comments

3CordGuy picture 3CordGuy  路  3Comments

signalwerk picture signalwerk  路  3Comments