Troubleshooting
Common integration issues when using Rad UI in SSR frameworks, with portals, and around focus management.
For baseline SSR and no-JS guidance, see SSR & No-JS Fallback.
Hydration mismatches
Symptom: React warns that server HTML did not match the client, often on overlay or theme components.
Likely causes
- Reading
window,document, ormatchMediaduring render instead of inuseEffect. - Rendering different initial state on the server and client (for example, open dialogs or system theme resolution).
- Generating random IDs during render without a stable SSR strategy.
What to try
- Keep browser-only logic in effects or event handlers.
- Defer client-only UI behind a mounted flag when the initial visual state cannot match SSR output.
- Use explicit
appearanceonThemeinstead ofsystemwhen SSR must be deterministic.
Portal container issues
Symptom: Overlays render in the wrong place, inherit unexpected styles, or appear behind other UI.
Likely causes
- A global portal root outside the themed subtree, so portaled content misses theme tokens or
classNamespacescope. - Missing or duplicate
data-rad-ui-portal-rootcontainers when nestingThemeproviders. - Parent
overflow: hidden,transform, orfiltercreating a containing block that traps fixed positioning.
What to try
- Wrap interactive surfaces with
Themeso each theme subtree owns its portal root. - Prefer Rad UI's built-in portal targets tied to the active
Themecontext. - Inspect the DOM to confirm portaled nodes mount under the expected theme container.
Focus not restoring after close
Symptom: Focus disappears, jumps to the body, or lands on an unexpected element after closing a dialog, popover, or menu.
Likely causes
- The trigger element unmounted while the overlay was open.
- Multiple layered overlays closing in the wrong order.
- Custom
onOpenChangehandlers preventing the default close path before focus restoration runs. - Custom cleanup code calls
focus()synchronously while the focused element is being removed, leaving focus ondocument.body.
What to try
- Keep the trigger mounted while the overlay is open, or move focus explicitly in
onOpenChange. - Close nested overlays from the top layer down.
- Avoid calling
preventDefaulton dismiss events unless you also manage focus manually. - Defer manual focus restoration with
requestAnimationFrameso it runs after DOM removal.
Focus trapped incorrectly
Symptom: Tab cycles only inside an overlay when it should not, or escapes an open modal.
Likely causes
- Multiple focus scopes active at once.
- Portals rendering outside the modal subtree.
Dialog.ContentusesinitialFocus={false}, so focus can remain onDialog.Triggerwhen the dialog opens.- Browser extensions or third-party widgets inserting focusable nodes into the trap.
What to try
- Ensure only one modal
Dialogis marked open at a time unless using a documented nested pattern. - Verify portaled content belongs to the same overlay instance.
- Confirm that initial focus is enabled and that focus moves into the dialog when it opens.
- Test with extensions disabled when diagnosing focus order.
Overlays flash or fail on first paint
Symptom: SSR output shows closed triggers, then content flashes open, or overlays never open until a full reload.
Likely causes
- Open state initialized from
localStorageor URL params during the first client render without matching SSR. - Missing
"use client"boundary in Next.js App Router for interactive entrypoints.
What to try
- Initialize open state to a value that matches SSR, then sync from storage in
useEffect. - Mark Rad UI consumer components as client components in App Router apps.
Scroll locking side effects
Symptom: Background page cannot scroll after closing a dialog, or layout shifts when scrollbars disappear.
Likely causes
- Multiple components requesting scroll lock without balanced unlock on unmount.
- Nested overlays where only the top layer released scroll lock.
What to try
- Close overlays in reverse open order.
- Confirm no errors interrupted cleanup effects during fast route changes.
When to open an issue
Open a GitHub issue when you have a minimal reproduction, the Rad UI version, your framework version, and steps showing unexpected focus, portal, or SSR behavior compared to the docs.