gatsby icon indicating copy to clipboard operation
gatsby copied to clipboard

Regression: Gatsby Head API after 5.4.1 no longer working when gatsby-browser and gatsby-ssr with redux are used

Open princefishthrower opened this issue 2 years ago • 6 comments

Preliminary Checks

  • [X] This issue is not a duplicate. Before opening a new issue, please search existing issues: https://github.com/gatsbyjs/gatsby/issues
  • [X] This issue is not a question, feature request, RFC, or anything other than a bug report directly related to Gatsby. Please post those things in GitHub Discussions: https://github.com/gatsbyjs/gatsby/discussions

Description

Sorry for the long title, but I've discovered a regression in the Head API, it somehow has to do with using redux (and perhaps redux-persist) in the wrapRootElement within gatsby-browser.js and gatsby-ssr.js I have a standard Head usage, for example, my page/index.tsx:

export default function HomePage() {
  return (
    <h1>hello world</h1>
  );
}

export const Head = () => (
  <SEO
    title={"Home"}
    description={`My description.`}
  />
);

I saw for 5.6.X that a new way of using the Head API is possible, but to be clear, this isn't the only way to use the Head API, correct? This 'old' way as I've shown above should still work as far as I can tell.

Now, the Head API works as expected, until you are beyond 5.4.1 and you don't use redux in wrapRootElement. But if both of these are true, you will find the elements you define in Head are not hydrated during builds (though they appear to be 'working' whenever you run the site in development mode)

Anyway, to get my SEO to work again, I've reverrted to 5.4.1. No idea at the internals that could be causing this, I could potentially give it a look later but don't have time right now.

And before anyone complains that this is a redux or redux-persist issue, it can't be, because as I said, downgrading to 5.4.1 everything is working as expected.

Reproduction Link

https://github.com/princefishthrower/gatsby-head-issue

Steps to Reproduce

  1. Clone repro repo
  2. npm install
  3. gatsby build
  4. gatsby serve
  5. See that the title, which should be "Home Page" does not display, because the <title> tag is not in <head>.

If you downgrade to [email protected] npm install [email protected], clean, build, and serve, you'll find that the title is working again.

Expected Result

Elements defined in Head should appear in <head>.

Actual Result

Elements defined in Head do not appear in <head>.

Environment

System:
    OS: macOS 12.5.1
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.12.1 - ~/.nvm/versions/node/v18.12.1/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 8.19.2 - ~/.nvm/versions/node/v18.12.1/bin/npm
  Languages:
    Python: 2.7.17 - /usr/local/bin/python
  Browsers:
    Chrome: 110.0.5481.177
    Firefox: 110.0
    Safari: 15.6.1
  npmPackages:
    gatsby: ^5.7.0 => 5.7.0
  npmGlobalPackages:
    gatsby-cli: 5.4.0

Config Flags

No response

princefishthrower avatar Feb 24 '23 09:02 princefishthrower

I can reproduce with repro repo (production build not working producing <title> tag, while develop working just fine). react-redux <Provider> alone works fine, it's the <PersistGate> that seems to cause problems - yet to dive more but my hunch is that this provider/util/wrapper might use <Suspense> or something similar (given the loading prop) and that part might break proper head extraction

pieh avatar Feb 24 '23 09:02 pieh

OP here, any update on this or an idea of what the issue is?

princefishthrower avatar Aug 03 '23 10:08 princefishthrower

Any news on this? Updates to the state of the context provider injected via wrapRootElement do not seem to be picked up in the Head API.

marijoo avatar Sep 04 '23 15:09 marijoo

I can also reproduce this issue. I use both redux and redux-persist with their respective providers wrapping my SeoContext.Provider. Removing those providers fixes the issue (can confirm my SeoMetadata component is being server-side rendered), but obviously doing this isn't a sustainable option. Would love this to be fixed!

Mcdonamj087 avatar Sep 06 '23 03:09 Mcdonamj087

I believe this issue is also related #38269

Inspecting the react dom I can see 2 instances of the provider for redux also 2 duplicate react trees. I added key props to make sure this specific project wasn't doing something strange.

This image below only happens if Head API is used. Even an empty Head that just returns nothing. By removing the head export this bug goes away.

Screenshot 2023-09-15 at 12 38 22 AM

Unfortunately looks like my experiment in refactoring out React-Helmet is going to have to be reverted because this HeadAPI isn't ready for production use in relation to wrapRootElement and context providers.

    "@reduxjs/toolkit": "^1.9.5",
    "react-redux": "^8.1.1",
    "gatsby": "^5.10.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",

Dman757 avatar Sep 15 '23 07:09 Dman757

OP here, summer of 2024 now, can anyone from the team can point me to the affecting source code? More than happy to fix / PR this issue as Gatsby with Redux + Redux Persist is a favorite stack of mine... though slowly this starts to feel like one of those "eternity bugs"...

princefishthrower avatar Jul 29 '24 20:07 princefishthrower