Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug]: Initially opened dialog causes hydration error #3613

Open
2 tasks done
isRyven opened this issue Apr 27, 2024 · 1 comment
Open
2 tasks done

[bug]: Initially opened dialog causes hydration error #3613

isRyven opened this issue Apr 27, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@isRyven
Copy link

isRyven commented Apr 27, 2024

Describe the bug

Using a Dialog component, which is initially opened, throws a hydration exception.

image

image

image

Affected component/components

Dialog

How to reproduce

1. Initiate latest next project:

npx create-next-app@latest dialog-bug-shadcn --typescript --tailwind --eslint
cd  dialog-bug-shadcn

2. Initiate shadcn:

npx shadcn-ui@latest init

3. Add Dialog component:

npx shadcn-ui@latest add dialog

4. Use the Dialog component with open property set to true:

import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";

export default function Home() {
  return (
    <div className="p-4">
      <Dialog open={true} modal={false}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Are you absolutely sure?</DialogTitle>
            <DialogDescription>
              This action cannot be undone. This will permanently delete your
              account and remove your data from our servers.
            </DialogDescription>
          </DialogHeader>
        </DialogContent>
      </Dialog>
    </div>
  );
}

5. Run the next dev server:

npm run dev

Codesandbox/StackBlitz link

https://stackblitz.com/edit/stackblitz-starters-c11bus

Logs

Unhandled Runtime Error

Error: Hydration failed because the initial UI does not match what was rendered on the server.
See more info here: https://nextjs.org/docs/messages/react-hydration-error

Expected server HTML to contain a matching <div> in <div>.

<Home>
  <div>
  ^^^^^
    <$5d3850c4d0b4e6c7$export$3ddf2d174ce01153>
      <Provider>
        <_c1>
          <$5d3850c4d0b4e6c7$export$dad7c95542bacce0>
            <Provider>
              <$921a889cee6df7e8$export$99c2b779aa4e8b8b>
                <eval>
                  <eval>
                    <eval>
                      <eval>
                        <eval>
                          <$921a889cee6df7e8$export$99c2b779aa4e8b8b>
                            <eval>
                              <eval>
                                <eval>
                                  <eval>
                                    <eval>
                                      <eval>
                                        <eval>
                                          <eval>
                                            <div>

Callstack

throwOnHydrationMismatch
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (6981:1)
tryToClaimNextHydratableInstance
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (7016:1)
updateHostComponent$1
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (16621:1)
beginWork$1
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (18503:1)
HTMLUnknownElement.callCallback
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (20565:1)
Object.invokeGuardedCallbackImpl
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (20614:1)
invokeGuardedCallback
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (20689:1)
beginWork
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (26949:1)
performUnitOfWork
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (25748:1)
workLoopConcurrent
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (25734:1)
renderRootConcurrent
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (25690:1)
performConcurrentWorkOnRoot
node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js (24504:1)
workLoop
node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js (256:1)
flushWork
node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js (225:1)
MessagePort.performWorkUntilDeadline
node_modules/next/dist/compiled/scheduler/cjs/scheduler.development.js (534:1)

System Info

Sytem:

OS: macOS 14.4.1 23E224 arm64
Host: MacBookPro18,3
Kernel: 23.4.0
CPU: Apple M1 Pro
GPU: Apple M1 Pro

Browser:

Arc
Version 1.40.0 (49176)
Chromium Engine Version 124.0.6367.79

Before submitting

  • I've made research efforts and searched the documentation
  • I've searched for existing issues
@isRyven isRyven added the bug Something isn't working label Apr 27, 2024
@OmarAljoundi
Copy link

Hi @isRyven

According to the official Next.js documentation on hydration errors, a hydration error occurs when:

While rendering your application, there was a difference between the React tree that was pre-rendered from the server and the React tree that was rendered during the first render in the browser.

Since the dialog initially requires JavaScript to render, a discrepancy can arise. After the server renders the HTML, the client-side JavaScript executes and potentially introduces new HTML content, which may not match the HTML that was rendered by the server.

To solve this, you have two options:

  • Import the Dialog component dynamically on the client side and disable SSR (Server-Side Rendering) for it:
    const Dialog = dynamic(() => import('@/components/ui/dialog').then((mod) => mod.Dialog), { ssr: false });
  • Delay rendering until after the server has finished generating the HTML. This can be managed by checking a state that is set only on the client:
const [isClient, setIsClient] = useState(false);
useEffect(() => {
  setIsClient(true);
}, [])

When isClient is true, it indicates that the client has taken over rendering from the server.

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants