React 18: Hydration Issue caused by Indicator/ShadowPortal component
See original GitHub issuePreliminary Checks
- This issue is not a duplicate. Before opening a new issue, please search existing issues: https://github.com/gatsbyjs/gatsby/issues
- 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
When running Gatsby with React 18 (Concurrent mode) and onRecoverableError
callback provided to react’s hydrateRoot
/createRoot
functions, I get a Error: Hydration failed because the initial UI does not match what was rendered on the server
error.
The cause of this error seems to be the Indicator
resp. ShadowPortal
component of gatsby (included from .cache/shadow-portal.js
/ .cache/indicator.js
), as ShadowPortal
renders a span
element and Indicator
then renders div
elements inside that span, which is invalid.
The error occurs always in develop mode, and sometimes even in production builds.
If I disable the loading indicator (via http://localhost:8000/___loading-indicator/disable), the error doesn’t occur anymore.
Reproduction Link
https://github.com/kije/gatsby-bugreport-hydration-error-shadow-portal-indicator
Steps to Reproduce
- Checkout reprodution repo
- Start gatsby with
npm run develop
Expected Result
The hydration error described above does not occur
Actual Result
Hydration error described above occurs
Environment
System:
OS: macOS 12.3.1
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Shell: 5.8 - /bin/zsh
Binaries:
Node: 18.4.0 - ~/.nvm/versions/node/v18.4.0/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 8.13.0 - ~/.nvm/versions/node/v18.4.0/bin/npm
Languages:
Python: 2.7.18 - /Library/Frameworks/Python.framework/Versions/2.7/bin/python
Browsers:
Chrome: 103.0.5060.53
Firefox: 102.0
npmPackages:
gatsby: ^4.17.2 => 4.17.2
gatsby-alias-imports: ^1.0.6 => 1.0.6
gatsby-parcel-config: file:./.gatsby/fixed-packages/gatsby-parcel-config => 0.9.0
gatsby-plugin-bundle-stats: ^3.3.10 => 3.3.10
gatsby-plugin-image: ^2.17.0 => 2.17.0
gatsby-plugin-layout: ^3.17.0 => 3.17.0
gatsby-plugin-lodash: ^5.17.0 => 5.17.0
gatsby-plugin-lomobox-file-downloader: file:./plugins/file-downloader => 1.0.0-rev4
gatsby-plugin-next-seo: ^1.10.0 => 1.10.0
gatsby-plugin-nprogress: ^4.17.0 => 4.17.0
gatsby-plugin-offline-next: ^5.2.3 => 5.2.3
gatsby-plugin-optimize-svgs: ^1.0.5 => 1.0.5
gatsby-plugin-persist-cache: ^0.0.2 => 0.0.2
gatsby-plugin-postcss: ^5.17.0 => 5.17.0
gatsby-plugin-preconnect: ^1.3.0 => 1.3.0
gatsby-plugin-purgecss: ^6.1.2 => 6.1.2
gatsby-plugin-react-i18next: ^1.2.2 => 1.2.2
gatsby-plugin-react-svg: ^3.1.0 => 3.1.0
gatsby-plugin-realfavicongenerator: ^0.1.2 => 0.1.2
gatsby-plugin-robots-txt: ^1.7.1 => 1.7.1
gatsby-plugin-sharp: file:./plugins/shared/gatsby-plugin-sharp => 4.4.0-rev11
gatsby-plugin-sitemap: ^5.17.0 => 5.17.0
gatsby-plugin-split-css: ^2.0.2 => 2.0.2
gatsby-plugin-styled-components: ^5.17.0 => 5.17.0
gatsby-plugin-ts-checker: ^1.1.0 => 1.1.0
gatsby-plugin-typegen: ^3.0.0 => 3.0.0
gatsby-plugin-webfonts: ^2.2.2 => 2.2.2
gatsby-plugin-webpack-bundle-analyser-v2: ^1.1.27 => 1.1.27
gatsby-source-craft: https://github.com/kije/gatsby-source-craft.git#gatsby-v4-patched => 3.0.1
gatsby-source-filesystem: ^4.17.0 => 4.17.0
gatsby-source-iubenda-documents: ^2.1.0 => 2.1.0
gatsby-transformer-remark: ^5.17.0 => 5.17.0
gatsby-transformer-sharp: ^4.17.0 => 4.17.0
gatsby-transformer-sqip: file:./plugins/shared/gatsby-transformer-sqip => 4.4.0-rev27
npmGlobalPackages:
gatsby-cli: 4.17.1
Config Flags
No response
Issue Analytics
- State:
- Created a year ago
- Reactions:5
- Comments:5 (2 by maintainers)
Hi @kije, thanks for the description and reproduction.
I tested these six scenarios with the latest Gatsby version (
gatsby@4.18.0
):Not using
replaceHydrateFunction
(unchanged minimal starter):Using
replaceHydrateFunction
from reproduction:It makes sense that prod doesn’t have this issue since the related code isn’t used in prod but I included anyway it since it was mentioned.
So breaking it down there are two things to fix/improve:
DEV_SSR
replaceHydrationFunction
docs with an example that works in React 18 https://www.gatsbyjs.com/docs/reference/config-files/gatsby-browser/#replaceHydrateFunctionThe second point should help shed light on why the
replaceHydrationFunction
usage in @kije’s reproduction repo has the error too.Thanks for the fix @pieh!