theme-ui icon indicating copy to clipboard operation
theme-ui copied to clipboard

Gatsby hydration/client-side re-render issue

Open ftes opened this issue 4 years ago • 4 comments

Describe the bug The first client-side re-render (or hydration?) causes the global styles (styles.global) to get "lost".

Using:

  • gatsby
  • reflexjs

To Reproduce

  1. Add page
// src/pages/hydration-issue.js
import { Link } from "gatsby"
import * as React from "react"

export default function HydrationIssuePage() {
  return (
    <div sx={{bg: "red"}}>
      <div sx={{variant: "container"}}>
        <h1>Hello</h1>
        <p>World!</p>
        <Link to="/"><span sx={{variant: "text.link"}}>Go home</span></Link>
      </div>
    </div>
  )
}
  1. Run gatsby build && gatsby serve
  2. Open browser, hover over link in page hydration-issue

Expected behavior The styles remains mostly unchanged when hovering over the link. Only the link hover style should be applied. The global styles should not suddenly get "lost".

Screenshots See above.

Additional context The issue does not occur in dev mode (gatsby develop).

ftes avatar Mar 11 '21 20:03 ftes

Also posted here: https://github.com/reflexjs/reflexjs/issues/154

ftes avatar Mar 11 '21 20:03 ftes

Update: The issue seems to be triggered by the gatsby prefetch mechanism when hovering over the link. Not all links cause the styles to break. But certain ones always do, every time.

I cannot yet pinpoint what distinguishes those links from others

ftes avatar Mar 11 '21 20:03 ftes

Update: I narrowed down which prefetched pages cause the bug. Affected: Hovering over a link to any page that executes the @emotion/react keyframes method.

Example:

// src/pages/start-page.js
import * as React from "react"
import {Link} from "gatsby"
const StartPage = () => <Link to="/page-with-keyframes">Go to page with @emotion/react keyframes call</Link>
export default StartPage

// src/pages/page-with-keyframes.js
import * as React from "react"
import {keyframes} from "@emotion/react"

const unused = keyframes``
const PageWithKeyframes = () => <div>Empty</div>
export default PageWithKeyframes

Note that keyframes is called, but the result is not actually consumed anywhere.

ftes avatar Mar 11 '21 21:03 ftes

Thanks for the issue, and this thorough investigation, @ftes! :pray:

hasparus avatar Mar 12 '21 22:03 hasparus

I just tried digging into this again, using both Gatsby v4 & v5, & neither in dev nor prod can I recreate. Are you still seeing this issue @ftes?

Gatsby v4 site: https://gatsby-1568-ndqk8610h-systemui.vercel.app/ (source)
Gatsby v5 site: https://gatsby-1568-enqynq64w-systemui.vercel.app/ (source)

lachlanjc avatar Nov 15 '22 04:11 lachlanjc

I've since switched tech stacks, so I can't say if the issue still exists. I suggest closing the bug since nobody else complained and you couldn't reproduce it.

ftes avatar Nov 15 '22 07:11 ftes