Fix dialog SSR crash by gating DialogPortal to client

DialogPortal aliased Radix's Portal directly, which calls
createPortal(children, document.body) during render. Static
prerendering (e.g. /about via InquiryDialog) has no document
global and threw "document is not defined". Wrap it so the
portal only mounts client-side.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Exmd6Wn13TGp1sArgK7y4
This commit is contained in:
Rami Bitar
2026-06-30 16:11:22 -04:00
parent aa4900e0fb
commit 5b0dbb5e6e

View File

@@ -10,7 +10,26 @@ const Dialog = DialogPrimitive.Root;
const DialogTrigger = DialogPrimitive.Trigger;
const DialogPortal = DialogPrimitive.Portal;
// Only render the portal on the client. During SSR/static prerendering the
// `document` global doesn't exist, and React Dom's createPortal(children,
// document.body) inside Radix's Portal would throw "document is not defined".
const DialogPortal = ({
children,
...props
}: React.ComponentPropsWithoutRef<typeof DialogPrimitive.Portal>) => {
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => {
setMounted(true);
}, []);
if (!mounted) {
return null;
}
return <DialogPrimitive.Portal {...props}>{children}</DialogPrimitive.Portal>;
};
DialogPortal.displayName = DialogPrimitive.Portal.displayName;
const DialogClose = DialogPrimitive.Close;