gatsby: Gatsby serve | Styles are not loaded on initial site load

Description

Currently, when running gatsby build && gatsby serve and navigating to the page where the site is being served, some of the styles are not loading initially. However, if I navigate to any page within the app - it loads all the styles correctly. I am trying to isolate which exactly styles are not loaded, but there are no console/network errors at the moment.

I am using jsxstyle. There are no issues when running dev build.

Steps to reproduce

This is happening in a private organization project, but I can put together a repo to reproduce.

Expected result

All styles are loaded on initial page load.

Actual result

Some of the styles are not loaded initially.

Environment

System:
    OS: macOS High Sierra 10.13.6
    CPU: x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 10.12.0 - /usr/local/bin/node
    Yarn: 1.10.1 - /usr/local/bin/yarn
    npm: 6.4.1 - /usr/local/bin/npm
  Browsers:
    Chrome: 69.0.3497.100
    Firefox: 62.0.3
    Safari: 12.0
  npmPackages:
    gatsby: 2.0.18 => 2.0.18
    gatsby-plugin-flow: 1.0.2 => 1.0.2
    gatsby-plugin-jsxstyle: 0.0.3 => 0.0.3
    gatsby-plugin-react-helmet: 3.0.0 => 3.0.0
  npmGlobalPackages:
    gatsby-cli: 1.1.18
    gatsby: 1.9.277

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 38
  • Comments: 49 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Im really just starting out with web dev, so I might be wrong. Having said that, Im building a gatsby site with Material UI and was experiencing the same issues. Styles not being injected when loading site at index page, but after going to another page where the same component can be found styles are loaded correctly, and if you go back to the index page you now see everything correctly.

I tried a couple of things, but what solved it was adding to my gatsby-config.js the following:

{ resolve: 'gatsby-plugin-material-ui', // If you want to use styled components you should change the injection order. options: { stylesProvider: { injectFirst: true, }, },

Dont really understand much, except mi site is now working correctly.

Hey, I have the same issue, but I just follow this guide https://www.gatsbyjs.org/packages/gatsby-plugin-styled-components/?=styled and now my website is working correctly.

Regards.

Update (in case anyone comes looking for help): I just ended up following the material-ui gatsby example: https://github.com/mui-org/material-ui/tree/master/examples/gatsby

This is a great thread! I’m wondering if anyone experiencing this problem with emotion has come up with a reliable solution? My problem seems isolated to components that combine css and withTheme from @emotion/react and styled from @emotion/styled. Per the common descriptions here, initially many components load unstyled, but styles pop-in on browser refresh.

Each component looks like

components
|- AppBar
  |- AppBar.jsx // exports UnstyledAppBar functional component
  |- styles.js // exports styles() which returns css`...`
  |- index.js // exports withTheme(styled(UnstyledAppBar)`${styles}`), i.e. a styled component with theme injected

Further, the styles that fail to work on first load are the styles derived from the theme prop.

In other words

// styles.js
const styles = (props) => {
  const { theme } = props;

  return css`
    margin-left: 24px;
    margin-right: ${spacingSizeMedium}; // evaluates to 24px
  `;
}

The margin-left style renders immediately but margin-right requires refresh.

This issue does not appear in Gatsby development mode, but occurs in Gatsby builds.

I have never used jsxstyle, but I had a similar issue with material-ui.

The problem for me was that in Gatsby, each page produces a separate html tree, so the material-ui class-name generator was assigning the same class name to different components on different pages.

Material-ui has an option to customize the generated class prefix, so my solution was to use a different prefix for each page. Not sure if jsxstyle has a similar configuration option.

Can confirm, as @chri5bot stated, if you are using styled-components, installing gatsby-plugin-styled-components as well as babel-plugin-styled-components should do the tricks.

Had similar issue for like a week, and now my app is working like a charm. 👍🏼

Hey, I have the same issue, but I just follow this guide https://www.gatsbyjs.org/packages/gatsby-plugin-styled-components/?=styled and now my website is working correctly.

Regards.

Hey, thanks @chri5bot ! My site is working because of this as well.

@AryanJ-NYC if you want to use withStyles on multiple pages, just pass a unique prefix as a prop to the Layout component and forward it to JssProvider. Looking at your repo, you’d modify the Layout component like this:

// Layout.js

const TemplateWrapper = ({ children, classes, classPrefix }) => {
  const generateClassName = createGenerateClassName({
    productionPrefix: classPrefix
  });

  return (
    <>
      <Helmet title="The WebDev Coach" />
      <JssProvider generateClassName={generateClassName}>
        // ...
      </JssProvider>
    </>
  );
});

And then instantiate Layout like so:

// about-page.js
  
const AboutPage = () => <Layout classPrefix='ap'> { /* ... */ } </Layout>

Hey, I have the same issue, but I just follow this guide https://www.gatsbyjs.org/packages/gatsby-plugin-styled-components/?=styled and now my website is working correctly.

Regards.

Hey, thank you so much for this 😃

Ah neat, looks like Gatsby passes a Cache instance to each plugin function:

https://github.com/gatsbyjs/gatsby/blob/fa8ef4e/packages/gatsby/src/utils/api-runner-node.js#L103-L123

This seems to do the trick:

const JsxstylePlugin = require('jsxstyle-webpack-plugin');
const path = require('path');

exports.onCreateWebpackConfig = ({ actions, cache }) => {
  actions.setWebpackConfig({
    plugins: [new JsxstylePlugin()],
    module: {
      rules: [
        {
          test: /\.(?:jsx?|tsx)$/,
          use: [
            {
              loader: JsxstylePlugin.loader,
              options: {
                cacheFile: path.resolve(cache.directory, 'style-key-cache.txt'),
              },
            },
          ],
        },
      ],
    },
  });
};

Since this issue is an implementation bug (fixed in https://github.com/jsxstyle/jsxstyle/pull/123, thx @aamorozov) I’d say it can be closed here.

Had the same problem, with style not loading initially (it created a really awful visual glitch).

I use JSS to style my components, and because the gatbsy-plugin-jss doesn’t offer ways to configure my own global style sheet, at some point I completely removed the plugin from my project and did the configuration manually in my gatsby-browser.js

I added the plugin back. Adding that one line in gatsby-config.js, without changing anything to my gatsby-browser.js solved the problem as well:

plugins: [
  … // other plugins
  `gatsby-plugin-jss`
  ]

I took out the react-helmet and it did seem unnecessary. When I deploy to netlify it still shows the unstyled lists before final render. I think if you’re looking at ‘gatsby develop’, you won’t see the problem, only when deployed on netlify. I’m trying to remove emotion from the Layout component. It’s using an Emotion Theme Provider to give the feature that allows you to control background color. Thanks for finding the fact that you don’t need to React-Helmet!

I ended up not using a withStyles material-ui method call and all is well.