style omited in production env when reload page
meritozh opened this issue · comments
Describe the bug
I use MDXProvider
to override default components to achieve code highlight. Everything is ok in development env, but in production env, if I reload current page, style injectted by wrapRootElement
omitted.
To Reproduce
demo
- clone this demo repo
- yarn install
- npx gatsby build
- npx gatsby serve
- open
http://localhost:9000
, jump to page-3, code highlight works well. - reload page, highlight lost.
Screenshots
reload:
I'm not sure it is caused by gatsby-plugin-mdx
(1.0), need test
Because the wrapRootElement
isn't used in gatsby-ssr
, the styles are not included until the gatsby-browser processing runs. Add the wrapRootElement
that you use in gatsby-browser
to gatsby-ssr
as well.
let me know if this doesn't fix your issue :)
@ChristopherBiscardi Yes, it works now, but I'm confused.
See the second snapshot, the code is highlighted.
Only the background color omitted, because it omit the class name language-c
if I reload page 3:
It doesn't omit the class name token
keyword
which produced by prism-react-renderer
.
But If I first route to homepage, then jump to page 3, everything is ok:
Why the output is not consistent?
The output is not consistent in that repo because the gatsby-ssr
and gatsby-browser
include different MDXProvider
components (ssr
has none, browser
has the Code
), which means the prism-react-renderer component is only being applied by gatsby-browser
. The HTML generated by gatsby build
is generated with gatsby-ssr
, resulting in the original set of HTML. The "second rendering" is done at runtime via with the additional code components however, there's a difference between the first runtime render and the runtime render when switching pages. The first runtime render (when refreshing page-3) causes a rehydration of React on top of the original HTML. The second runtime render (when switching pages) is generating brand new DOM without the underlying HTML.
So while I haven't investigated this in depth in this case, my best guess as to why there's a difference is that the rehydration render when combined with the original "faulty" HTML causes React to short-circuit some of it's reconciliation when compared to the "raw" render, which renders completely from scratch. It's like having some stale state around.