FAQ and troubleshooting
Answers for modal stacks, scroll views, native overlays, and common setup errors.
Can multiple modals be open?
Yes. Every show pushes an independent stack entry with its own ID, configuration, promise, and
content.
Can a modal contain a ScrollView?
Yes, but disable the modal's swipe gesture so it does not compete with scrolling:
magicModal.show(() => <ScrollableModal />, {
swipeDirection: undefined,
});Magic Modal does not implement snap points or nested scrolling.
Why does Gesture Handler say there is no root view?
Expo and native applications render the portal inside GestureHandlerRootView:
<GestureHandlerRootView style={{ flex: 1 }}>
<App />
<MagicModalPortal />
</GestureHandlerRootView>A web-only Next.js application mounts the portal directly in its Client Component shell.
Why does magicModal say the portal was not found?
An imperative call ran before MagicModalPortal mounted, or the active React tree does not contain
one. Mount one portal at the app root and avoid module-scope show calls during startup.
What accessibility behavior comes from the portal?
The top stack entry receives modal semantics and an accessible name from the accessibilityLabel
option. Web also traps focus, handles Escape, and restores focus after close. The modal component
provides its visible heading, control labels, form errors, and status announcements. Follow the
accessibility guide for examples and the test checklist.
Why is the modal above an image picker on iOS?
The full-window overlay is enabled. Call magicModal.disableFullWindowOverlay() before opening the
picker. Restore it in finally. See
native iOS overlays.
Does Gesture Handler 2 work?
Yes. Magic Modal 9 supports Gesture Handler 2.20+ and 3.x. Version 8.0.0 was the temporary exception.
How do I close a modal from outside it?
Keep the ID returned by show:
const { modalID } = magicModal.show(() => <StatusModal />);
magicModal.hide(undefined, { modalID });Inside modal content, prefer useMagicModal.