With certain combinations of styles, the SheetsRegistry should be cleared between rendered pages.
This repo has a simplified reproduction and tracks my fix for it:
https://github.com/cpboyd/gatsby-layout-mui-bug
Note: I'm not sure where resetting the SheetsRegistry
should occur. I just placed it after the ToString()
call because that seemed the easiest place to put it.
The pages should render consistently between the Javascript rendering and static rendering.
The styles were jumbled.
System:
OS: macOS High Sierra 10.13.6
CPU: x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 10.9.0 - /usr/local/bin/node
Yarn: 1.9.4 - /usr/local/bin/yarn
npm: 6.4.0 - /usr/local/bin/npm
Browsers:
Chrome: 68.0.3440.106
Safari: 11.1.2
npmPackages:
gatsby: ^2.0.0-rc.0 => 2.0.0-rc.0
gatsby-image: ^2.0.0-rc.0 => 2.0.0-rc.0
gatsby-plugin-google-analytics: ^2.0.0-rc.0 => 2.0.0-rc.0
gatsby-plugin-jss: ^2.0.2-rc.0 => 2.0.2-rc.0
gatsby-plugin-layout: next => 1.0.0-rc.0
gatsby-plugin-manifest: ^2.0.2-rc.0 => 2.0.2-rc.0
gatsby-plugin-offline: ^2.0.0-rc.0 => 2.0.0-rc.0
gatsby-plugin-react-helmet: ^3.0.0-rc.0 => 3.0.0-rc.0
gatsby-plugin-sharp: ^2.0.0-rc.0 => 2.0.0-rc.0
gatsby-plugin-typescript: ^2.0.0-rc.0 => 2.0.0-rc.1
gatsby-plugin-typography: ^2.2.0-rc.0 => 2.2.0-rc.0
gatsby-remark-external-links: ^0.0.4 => 0.0.4
gatsby-remark-images: ^2.0.1-rc.0 => 2.0.1-rc.0
gatsby-remark-responsive-iframe: ^2.0.0-rc.0 => 2.0.0-rc.0
gatsby-source-filesystem: ^2.0.1-rc.0 => 2.0.1-rc.0
gatsby-transformer-json: ^2.1.1-rc.0 => 2.1.1-rc.0
gatsby-transformer-remark: ^2.1.1-rc.0 => 2.1.1-rc.0
gatsby-transformer-sharp: ^2.1.1-rc.0 => 2.1.1-rc.0
npmGlobalPackages:
gatsby-cli: 1.1.58
gatsby-config.js
: N/A
package.json
: N/A
gatsby-node.js
: N/A
gatsby-browser.js
: N/A
The original gatsby-ssr.js
API started with a new SheetsRegistry
each time it rendered the page:
exports.replaceRenderer = (
{ bodyComponent, replaceBodyHTMLString, setHeadComponents },
{ theme = {} }
) => {
const sheets = new SheetsRegistry()
const bodyHTML = renderToString(
<JssProvider registry={sheets}>
<ThemeProvider theme={theme}>{bodyComponent}</ThemeProvider>
</JssProvider>
)
replaceBodyHTMLString(bodyHTML)
setHeadComponents([
<style
type="text/css"
id="server-side-jss"
key="server-side-jss"
dangerouslySetInnerHTML={{ __html: sheets.toString() }}
/>,
])
}
Now the variable is file scoped and seems to persist across renderings:
import React from "react"
import { JssProvider, SheetsRegistry, ThemeProvider } from "react-jss"
const sheets = new SheetsRegistry()
// eslint-disable-next-line react/prop-types,react/display-name
exports.wrapRootElement = ({ element }, { theme = {} }) => (
<JssProvider registry={sheets}>
<ThemeProvider theme={theme}>{element}</ThemeProvider>
</JssProvider>
)
exports.onRenderBody = ({ setHeadComponents }) => {
setHeadComponents([
<style
type="text/css"
id="server-side-jss"
key="server-side-jss"
dangerouslySetInnerHTML={{ __html: sheets.toString() }}
/>,
])
You are right. I think we would need to pass setHeadComponents
to wrapRootElement
so SheetsRegistry
could live just inside that function scope. Otherwise we would need to create dictionary (
Most helpful comment
You are right. I think we would need to pass) instead of single global registry.
setHeadComponents
towrapRootElement
soSheetsRegistry
could live just inside that function scope. Otherwise we would need to create dictionary (