remix-run / indie-stack

The Remix Stack for deploying to Fly with SQLite, authentication, testing, linting, formatting, etc.
https://remix.run/stacks
MIT License
1.13k stars 315 forks source link

Remix and Cypress hydration problem #220

Open triptec opened 1 year ago

triptec commented 1 year ago

Have you experienced this bug with the latest version of the template?

Yes

Steps to Reproduce

Setup the template and run npm test:e2e:dev and run the smoke test in either chrome or electron and open the console.

Expected Behavior

That there shouldn't be any hydration probelms

Actual Behavior

The console is filled with: react-dom.development.js:86 Warning: Expected server HTML to contain a matching <meta> in <head>. at meta at head at html at App at RemixRoute (http://localhost:3000/build/_shared/chunk-DRRZ7FOQ.js:7074:3) at RenderedRoute (http://localhost:3000/build/_shared/chunk-DRRZ7FOQ.js:4543:5) at RenderErrorBoundary (http://localhost:3000/build/_shared/chunk-DRRZ7FOQ.js:4932:9) at Routes (http://localhost:3000/build/_shared/chunk-DRRZ7FOQ.js:4803:5) at Router (http://localhost:3000/build/_shared/chunk-DRRZ7FOQ.js:4750:15) at RouterProvider (http://localhost:3000/build/_shared/chunk-DRRZ7FOQ.js:4699:5) at RemixErrorBoundary (http://localhost:3000/build/_shared/chunk-DRRZ7FOQ.js:6693:5) at RemixBrowser (http://localhost:3000/build/_shared/chunk-DRRZ7FOQ.js:8138:55) printWarning @ react-dom.development.js:86 error @ react-dom.development.js:60 warnForInsertedHydratedElement @ react-dom.development.js:10499 didNotFindHydratableInstance @ react-dom.development.js:11458 warnNonhydratedInstance @ react-dom.development.js:12385 tryToClaimNextHydratableInstance @ react-dom.development.js:12534 updateHostComponent @ react-dom.development.js:19902 beginWork @ react-dom.development.js:21618 beginWork$1 @ react-dom.development.js:27426 performUnitOfWork @ react-dom.development.js:26560 workLoopConcurrent @ react-dom.development.js:26543 renderRootConcurrent @ react-dom.development.js:26505 performConcurrentWorkOnRoot @ react-dom.development.js:25738 workLoop @ scheduler.development.js:266 flushWork @ scheduler.development.js:239 performWorkUntilDeadline @ scheduler.development.js:533 react-dom.development.js:12507 Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server. at throwOnHydrationMismatch (react-dom.development.js:12507:9) at tryToClaimNextHydratableInstance (react-dom.development.js:12535:7) at updateHostComponent (react-dom.development.js:19902:5) at beginWork (react-dom.development.js:21618:14) at HTMLUnknownElement.callCallback2 (react-dom.development.js:4164:14) at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16) at invokeGuardedCallback (react-dom.development.js:4277:31) at beginWork$1 (react-dom.development.js:27451:7) at performUnitOfWork (react-dom.development.js:26560:12) at workLoopConcurrent (react-dom.development.js:26543:5)

triptec commented 1 year ago

I've been debugging this as it makes our e2e test flaky due to re-renders and with that we get detached elements. Here's some discussion discussion

Could the problem be that cypress injects quite a lot of stuff into the html? https://github.com/cypress-io/cypress/blob/master/packages/proxy/lib/http/response-middleware.ts#L540

That's my prime suspect as I don't have any problems with hydration outside of cypress.

triptec commented 1 year ago

If I disable the code injection cypress (skip the MaybeInjectHtml middleware) does I don't get any hydration errors, that also breaks cypress.

ConorTighe commented 1 year ago

Did you ever fix this?

triptec commented 1 year ago

No and not sure if there’s a simple solution either, I’ve since moved on from cypress to playwright.

awweather commented 1 year ago

@triptec I have encountered the same issue. No workaround right now, will consider moving on from cypress

charesbast commented 1 year ago

The issue is not tied to the indie stack actually, but I'm not sure the issues here have the same visibility as those in the remix main repository. Still no answer from the dev team 😢

Should we move the issue to the main repo ? 🤷🏻‍♂️

antonkri97 commented 1 year ago

Relates to https://github.com/remix-run/remix/issues/4822

I think this can be closed

Aebrathia commented 3 months ago

Some workaround I found to avoid issues caused by the dom being trashed by the hydration while the test is running.

// cypress/support/commands.ts
Cypress.Commands.overwrite('visit', (originalFn, ...args) => {
  originalFn(...args);
  cy.get('#__is_hydrated__').should('exist');
});
// app/root.tsx
import { ClientOnly } from 'remix-utils/client-only';

export default function App() {
  return (
    <>
      <YourAppCode />
      {/* Avoid workaround from being in the production build */}
      {process.env.NODE_ENV === 'development' ? (
        <ClientOnly>{() => <div id="__is_hydrated__"></div>}</ClientOnly>
      ) : null}
    </>
  );
}