Mount-gate SheetPortal for SSR safety

Defensive guard so the portal only mounts client-side. Radix's Portal is
already SSR-safe, so this is belt-and-suspenders.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RCfQKfr64YJbFRs3Ai9v2
This commit is contained in:
Rami Bitar
2026-06-30 17:26:45 -04:00
parent 5b0dbb5e6e
commit 95ad3c9d02

View File

@@ -25,6 +25,15 @@ function SheetClose({
function SheetPortal({ function SheetPortal({
...props ...props
}: React.ComponentProps<typeof SheetPrimitive.Portal>) { }: React.ComponentProps<typeof SheetPrimitive.Portal>) {
// Radix's Portal calls createPortal(children, document.body) as soon as it
// renders. During static prerendering there's no `document`, so gate the
// portal behind an effect that only runs in the browser. Closed sheets
// render nothing on the server anyway, so there's no visual/hydration change.
const [mounted, setMounted] = React.useState(false)
React.useEffect(() => setMounted(true), [])
if (!mounted) return null
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} /> return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
} }