Skip to content

Hydration errors in Cypress when using React 18, Next, and server components #27204

Open
@liambutler

Description

@liambutler

Workaround: #27204 (comment)

Current behavior

I’ve got a Next app running React 18. In the next.config.js, it has been configured with appDir to support Server Components. When running Cypress and accessing the page, I’m getting the following React errors:

  • (uncaught exception)Error: Hydration failed because the initial UI does not match what was rendered on the server. Warning: Expected server HTML to contain a matching <script> in <head>. See more info here: https://nextjs.org/docs/messages/react-hydration
  • 
(uncaught exception)Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.

However, I do not see these hydration issues when accessing the page via browser, so it’s surprising to see them when running Cypress.

Steps to replicate:

  1. Clone repo and run npm install
  2. Run npm run e2e
  3. Visit http://localhost:3000 in your browser and check for console errors
  4. Run the spec app.cy.ts

Here's what I see in Cypress:
Screenshot 2023-07-05 at 16 14 00

It's not there when visiting the app via browser:
Screenshot 2023-07-05 at 16 21 08

The error will no longer appear if you remove the <script> tag on line 10 of layout.tsx (link to repro code)
Screenshot 2023-07-05 at 16 14 33

Seeing as this script tag isn't causing errors when accessing via the browser, I can only conclude that it's being caused by how Cypress is loading this page when React Server Components are present

The error occurs both when the app is running in dev mode, and when you visit the application in production mode after running build and start. In production mode, the errors are minified:

  • (uncaught exception)Error: Minified React error #418; visit https://reactjs.org/docs/error-decoder.html?invariant=418
  • (uncaught exception)Error: Minified React error #423; visit https://reactjs.org/docs/error-decoder.html?invariant=423

I’ve seen this issue raised in a few places. The suggestion I usually see is to prevent the tests from failing due to this uncaught exception (eg here), or to catch the issue in the application (Cypress docs)

As far as I have managed to understand, there should never be a hydration mismatch in a server rendered component since there is no client rendering to match it to. And when accessing the app via the browser, there are no mismatch errors. So I can only conclude that the issue stems from how Cypress is loading the page.

Desired behavior

Cypress should not be causing uncaught exceptions. Any exceptions that occur should also be triggered under the same conditions via browser

Test code to reproduce

https://github.com/liambutler/cypress-react-next-hydration-issue

Cypress Version

12.16.0

Node version

18.16.0

Operating System

MacOS 13.4.1

Debug Logs

No response

Other

Edit 8th November 2023- since updating Next.js from 13.4.2 to 13.5.6, we are also seeing this uncaught exception:

This also only appears when Cypress is being injected into the browser

Metadata

Metadata

Assignees

No one assigned

    Labels

    E2EIssue related to end-to-end testingTriagedIssue has been routed to backlog. This is not a commitment to have it prioritized by the team.existing workaround

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions