gatsby: Server-side-rendered styles are missing and/or incorrect

Description

I’ve built multiple sites/apps with Gatsby already, but that’s the first time I encounter such an issue.

I’m working on an app based on Gatsby and Material UI.

GitHub issues reporting similar, but not the same behavior that I reviewed and tested #9911, #12360, #5100, #3741.

GIF/recording of the issue https://monosnap.com/file/gQ7jH0YQ4O39LpHhL8DOL40eufnbbY

Sometimes, on initial page load (server-side-rendered per my understanding) the styles get totally messed up. This does not happen on subsequent (client-side) rendered pages, but only on the initial page load. Unfortunately, it occurs randomly and not on every build.

Setup The setup of Gatsby and Material UI is based on MUI’s official Gatsby example. In short, gatsby-plugin-material-ui and changes to gatsby-browser.js and gatsby-ssr.js

This very same setup, as described in the GH project itself, works perfectly fine on other projects. Therefore, I speculate there’s something that we’re missing.

  • We do not use styled-components or any similar CSS-in-JS library and such doesn’t exist in package.json
  • The only .css files we have are placed at the top of gatsby-browser.js like this
import 'slick-carousel/slick/slick-theme.css';
import 'slick-carousel/slick/slick.css';
import '~components/bar-bat-mitzvah/raleway-font.css';
  • I tested using the gatsby-plugin-material-ui’s option for injectFirst as described here, but without any success.
  • Clearing all “Site Data” from the Developer Tools console seems to fix the issue which might be a hint to something wrong with cached styles by the gatsby-plugin-offline
  • In addition, I tested many of the solutions in the mentioned GH issues, but none of these worked.

Steps to reproduce

Unfortunately, I can’t grant access to the project’s repository. I have the very same project setup as GH repository that I’m sharing for reference.

  • Developing and browsing the app locally using gatsby develop works perfectly fine.
  • Building using gatsby build passes just fine too. No warnings or errors.
  • Serving using gatsby serve serves the already built files. However, styles get messed up as described in this issue.

Expected result

It’s expected to load any styles properly on both initial and subsequent renders.

Actual result

The styles on initial-render get messed up and/or are corrupted. Please check the video recording at the top of the issue.

Environment

# gatsby info --clipboard
  System:
    OS: macOS 10.14.6
    CPU: (8) x64 Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 10.16.0 - ~/.nvm/versions/node/v10.16.0/bin/node
    Yarn: 1.13.0 - ~/.yarn/bin/yarn
    npm: 6.9.0 - ~/.nvm/versions/node/v10.16.0/bin/npm
  Languages:
    Python: 2.7.13 - /usr/local/bin/python
  Browsers:
    Chrome: 76.0.3809.132
    Firefox: 68.0.1
    Safari: 12.1.2
  npmPackages:
    gatsby: ^2.13.11 => 2.15.14 
    gatsby-plugin-create-client-paths: ^2.1.3 => 2.1.7 
    gatsby-plugin-facebook-pixel: ^1.0.3 => 1.0.3 
    gatsby-plugin-google-analytics: ^2.0.6 => 2.1.16 
    gatsby-plugin-mailchimp: ^5.1.0 => 5.1.2 
    gatsby-plugin-manifest: ^2.0.4 => 2.2.16 
    gatsby-plugin-material-ui: ^2.0.1 => 2.1.6 
    gatsby-plugin-nprogress: ^2.1.0 => 2.1.6 
    gatsby-plugin-offline: ^2.0.5 => 2.2.10 
    gatsby-plugin-react-helmet: ^3.0.0 => 3.1.7 
    gatsby-plugin-robots-txt: ^1.3.0 => 1.5.0 
    gatsby-plugin-root-import: ^2.0.5 => 2.0.5 
    gatsby-plugin-s3: 0.3.1 => 0.3.1 
    gatsby-plugin-sitemap: ^2.0.1 => 2.2.12 
    gatsby-plugin-webpack-size: 1.0.0 => 1.0.0 
    gatsby-source-prismic: 2.3.0-alpha.6 => 2.3.0-alpha.6 

Thank you for spending the time to look into this!

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 31 (20 by maintainers)

Most upvoted comments

Hey @eyalroth, I see issue #17914 that you created and can’t agree more. I will follow it.

I’m just pushing live the replaced hydration workaround you suggested. Note that I haven’t turned off gatsby-plugin-offline, so it’s still up & running.

// gatsby-browser.js
import ReactDOM from 'react-dom';
...
export function replaceHydrateFunction() {
  return (element, container, callback) => {
    ReactDOM.render(element, container, callback);
  };
}

I did gatsby build && gatsby serve and then tested it for a while. No glitches so far, but I don’t trust that since the issue is quite hard to catch.

I still can’t find a good way to reproduce it every time so we can debug it properly.

Anyway, I’ll try to get more people testing it and will report when there’s an update.

Let’s keep discussing in the “Meta” issue as writing across multiple different issues is just really cumbersome. https://github.com/gatsbyjs/gatsby/issues/17914

I think the bug is pretty specific to some shenanigans I’m pulling to make Gatsby run in directories other than the one the deploy command specifies with pathPrefix. In Gatsby 1, there was a global variable __PREFIX_PATHS__ that was apparently removed in Gatsby 2. We wrote some helper functions to normalize location.pathname and that code failed in Gatsby 2 because it thought there was no path prefix so it was failing to use the right page template for some files, causing the output to be not what was expected. I never discovered it because the path prefix isn’t needed when using develop or even build.

@monsieurBoutte @anthonytison This issue is tracked in #17914.

@SMerdzhanov Thx!! I banged my head for hours on this.

not sure why this is closed. I had to implement the same workaround

// gatsby-browser.js
import ReactDOM from 'react-dom'

// this is a hack to fix missing styles on refresh in production
// reference: https://github.com/gatsbyjs/gatsby/issues/17676#issuecomment-535796737
export function replaceHydrateFunction() {
  return (element, container, callback) => {
    ReactDOM.render(element, container, callback)
  }
}

Hey hey, just wanted to post for clarity/shared knowledge?

I’m currently building a Gatsby + MUI site with dynamic client-side routes and am experiencing some issues when my page gets rehydrated. Initial load to /something/:dynamic is fine (SSR looks as expected) but seemingly as soon as it’s rehydrated and my MUI components are mounted, custom styles get overwritten/disappear causing the page to look messed up ¯_(ツ)_/¯

I tried the solution mentioned above by @eyalroth and replaced my hydrate function with a rerender and that seems to have fixed my problems but I agree that that might be more of a workaround than a solution. I just wanted to post here since I found this thread in my search for an answer.

Best of luck!