Next.js SSR Hydration error with Modal component
Describe the bug With Next.js alongside flowbite-react, using Modals in the DOM causes errors with Next.js's builtin SSR.
To Reproduce Steps to reproduce the behavior:
- Initialize Next.js project (create-next-app)
- Setup tailwind, Flowbite, and flowbite-react library
- Import and use Modal component
- Open development page and see error
Simple repository to replicate the error: https://github.com/AhmedA1559/modal-example
Expected behavior Using modals should render properly with Next.js's SSR, producing no errors.
Screenshots

System information:
- Device: macOS M1 Pro (2021)
- Resolution: 3024×1964
- OS: macOS
- Browser: Safari
- Version: Version 15.4 (17613.1.17.1.13)
Project information:
npm list --depth=0 ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] ├── [email protected] └── [email protected]
I also got similar errors and got it fixed in multiple ways:
One would be by wrapping the Modal component in a Suspense component, which was introduced in React 18 without being experimental anymore.
Another solution is by using useEffect and states.
useEffect (in my example) will be triggered when the HTML was fully rendered.
You could do something like this to have your Modal shown after the site was rendered.
// ...
const [isLoading, setIsLoading] = useState(false)
useEffect(() => {
setIsLoading(true)
}, [])
// ....
return (
// ...
{
isLoading ? <Modal></Modal> : null
}
)
An example how I use this fix currently would be this (and the following) line(s) in my component. The first fix can be found in this line.
Possible explanations why this might happen in Next.js as well as further fixes can be found
- in this answer here by juliomalves on StackOverflow
- and in this endless discussion at the repo of Next.js: https://github.com/vercel/next.js/discussions/35773
I've tried to play around with this but I'm honestly stumped. My understanding is that this happening because the Modal is created in a React.Portal. There's no HTML delivered to the spot where the Modal is actually declared. But I don't know how to help next understand/deal with that.
Fixed.