Gatsby: Site's Server rendered components not getting cleaned up in browser

Created on 8 Feb 2020  路  10Comments  路  Source: gatsbyjs/gatsby

Description

With two of my site's components, the NavBar and the CookieConsentForm. Multiple instances are present on load. It appears that the components created during the build, which I imagine are created using the component tree described in the gatsby-ssr.js are overriding OR existing with the components described in the gatsby-browser.js file.

So in the example of the NavBar, the component looks a little like this

function NavBar() {
  <Router>
    <SimpleNavBar path="/landing-page/" />
    <NavBar default path="/" />
  </Router>
}

This displays the right components at the right routes when I start my development server locally. I imagine this is because Gatsby's building the component tree according to gatsby-browser.js file. When I run the production build and serve it, and navigate to the landing page, the majority of the styles of NavBar component are present, with some of the content of the SimpleNavBar also being present. It's as if Gatsby has merged the components together.

A similar thing happens in my CookieConsentForm component. From a component standpoint it's just a div container, with some text and a button inside of it. When I run my development server, it appears just as it should. When I run my production build, it displays as it should, and when I click the button (to acknowledge that I accept the cookie terms), it closes the component rendered by the gatsby-browser.js, but keeps the container from the server-rendered component.

My current workaround is to remove the CookieConsentForm and NavBar from the server-rendered components. I don't mind doing this for the CCF, but with the NavBar only being rendered on the browser, it makes my site feel jerky.

In the below image, you can see that I'm rendering two components, the top of the two is just the container and nothing else, while the other is contains the full component. It looks like the former is the left over from the server-rendered components.

image

Does Gatsby somehow use a component equality check to match components built with SSR and the ones built in the browser, and then swaps them out? If so it could make sense as top why it's causing the NavBar to break, because it's wrapped in a router (and I guess routing isn't something that the server is capable of dealing with).

Up until now I've kept the gatsby-browser and gatsby-ssr files in sync, but it's making less sense to do so, considering that I don't need to render a cookie consent form on the server, and I don't need to perform any of the initialisation that's required when a user starts a session.

Steps to reproduce

As for reproducing, it's only appeared now, and not before so I don't know what the cause of the issue is. I upgraded my packages a week or so ago, and had no issues until i created a brand new landing page today.

Environment

  System:
    OS: macOS Mojave 10.14.6
    CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
    Shell: 5.3 - /bin/zsh
  Binaries:
    Node: 12.14.1 - ~/.nvm/versions/node/v12.14.1/bin/node
    Yarn: 1.21.1 - /usr/local/bin/yarn
    npm: 6.13.4 - ~/.nvm/versions/node/v12.14.1/bin/npm
  Languages:
    Python: 2.7.10 - /usr/bin/python
  Browsers:
    Chrome: 79.0.3945.130
    Safari: 13.0
  npmPackages:
    gatsby: ^2.19.12 => 2.19.12 
    gatsby-image: ^2.2.40 => 2.2.40 
    gatsby-plugin-catch-links: ^2.1.25 => 2.1.25 
    gatsby-plugin-google-analytics: ^2.1.35 => 2.1.35 
    gatsby-plugin-manifest: ^2.2.41 => 2.2.41 
    gatsby-plugin-offline: ^3.0.34 => 3.0.34 
    gatsby-plugin-postcss: ^2.1.20 => 2.1.20 
    gatsby-plugin-robots-txt: ^1.5.0 => 1.5.0 
    gatsby-plugin-s3: ^0.3.2 => 0.3.2 
    gatsby-plugin-sharp: ^2.4.5 => 2.4.5 
    gatsby-plugin-sitemap: ^2.2.27 => 2.2.27 
    gatsby-plugin-styled-components: ^3.1.19 => 3.1.19 
    gatsby-plugin-typescript: ^2.1.27 => 2.1.27 
    gatsby-plugin-zopfli: ^1.3.2 => 1.3.2 
    gatsby-source-filesystem: ^2.1.48 => 2.1.48 
    gatsby-source-graphql: ^2.1.25 => 2.1.25 
    gatsby-transformer-sharp: ^2.3.14 => 2.3.14 
not stale confirmed frontend-core bug

Most helpful comment

Does Gatsby somehow use a component equality check to match components built with SSR and the ones built in the browser, and then swaps them out? If so it could make sense as top why it's causing the NavBar to break, because it's wrapped in a router (and I guess routing isn't something that the server is capable of dealing with).

It's not Gatsby directly that does that - it's React when it "hydrates" elements - React expects that DOM elements in SSR html match exactly what first render on the client/browser will be - if they don't match then it will lead to weird cases, that could explain what you are describing - check https://reactjs.org/docs/react-dom.html#hydrate for explainer on that.

I'm not sure if I ever tried using <Router> inside gatsby-browser or ssr, so behaviour might be undefined here - would be great if you could provide some reproduction sample of that

All 10 comments

Does Gatsby somehow use a component equality check to match components built with SSR and the ones built in the browser, and then swaps them out? If so it could make sense as top why it's causing the NavBar to break, because it's wrapped in a router (and I guess routing isn't something that the server is capable of dealing with).

It's not Gatsby directly that does that - it's React when it "hydrates" elements - React expects that DOM elements in SSR html match exactly what first render on the client/browser will be - if they don't match then it will lead to weird cases, that could explain what you are describing - check https://reactjs.org/docs/react-dom.html#hydrate for explainer on that.

I'm not sure if I ever tried using <Router> inside gatsby-browser or ssr, so behaviour might be undefined here - would be great if you could provide some reproduction sample of that

That's very useful to know! I'll try and create a reprocase.

Hey folks, here's a repro case for the bug: https://github.com/andrico1234/gatsby-ssr-bug-repro

As you can see, I've got a NavBar that renders conditionally based on the route, with the default nav bar being displayed when a user is on route other than '/'.

Run gatsby develop, and everything works fine.
Run gatsby build, and you'll see that there seems to be trouble in regards to how React handles hydrating the server-rendered components

@andrico1234 Could you specify what exactly the "trouble in regards to how React handles hydrating the server-rendered components" is, please? I built the project from your repo and both build and develop seem to work identically to me (routing works).

(I'm on Windows and Chrome/Firefox so not sure about Safari)

I'll create a gif/video of the issue I'm having when I get some time

Hiya!

This issue has gone quiet. Spooky quiet. 馃懟

We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 馃挭馃挏

My bad for forgetting to upload the video.

As you can see here, when i run locally the nav bar always displays correctly.

On home page it's yellow, on page two the background's white.

When I build and server my gatsby application, it looks like regardless of the page I enter, the default yellow background is displayed. Once the components rerender, everything works as expected.

https://streamable.com/y8j9o

Updated my last comment to add video

As a temprorary workaround, you could access current path through props of your page components and make your navbar a part of layout instead. See a couple of possible approaches here: https://github.com/gatsbyjs/gatsby/issues/8787#issuecomment-427216043

Hiya!

This issue has gone quiet. Spooky quiet. 馃懟

We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 馃挭馃挏

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Oppenheimer1 picture Oppenheimer1  路  3Comments

brandonmp picture brandonmp  路  3Comments

kalinchernev picture kalinchernev  路  3Comments

benstr picture benstr  路  3Comments

hobochild picture hobochild  路  3Comments