diff --git a/docs/manifest.json b/docs/manifest.json index 6cb771416c..d3e9e93e1a 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -3434,6 +3434,18 @@ } ] ] + }, + { + "title": "Utilities", + "collapse": false, + "items": [ + [ + { + "title": "``", + "href": "/docs/reference/components/utilities/portal-provider" + } + ] + ] } ] ] diff --git a/docs/reference/components/utilities/portal-provider.mdx b/docs/reference/components/utilities/portal-provider.mdx new file mode 100644 index 0000000000..61e1c54336 --- /dev/null +++ b/docs/reference/components/utilities/portal-provider.mdx @@ -0,0 +1,82 @@ +--- +title: '``' +description: The component allows Clerk floating UI elements to render inside custom containers instead of document.body. +sdk: astro, expo, nextjs, react, react-router, tanstack-react-start, vue +--- + +The `` component allows you to specify a custom container for Clerk floating UI elements (popovers, modals, tooltips, etc.) that use portals. Only Clerk components within the provider will be affected, components outside the provider will continue to use the default `document.body` for portals. + +This is particularly useful when using Clerk components inside external UI libraries like [Radix Dialog](https://www.radix-ui.com/primitives/docs/components/dialog) or [React Aria Components](https://react-spectrum.adobe.com/react-aria/components.html), where portaled elements need to render within the dialog's container to remain interactable. + +> [!CAUTION] +> This component is marked as `UNSAFE` because it is an escape hatch that modifies the portal behavior of Clerk components. Not all portal locations will work correctly—some may cause issues with styling, accessibility, or other functionality. Typically, it is best to portal to the root of your application (e.g., the `body` element), outside of any possible overflow or stacking contexts. Use `` only when necessary, such as when Clerk components are rendered inside external dialogs or popovers, or when you need to group all portalled elements into a single container at the root of your app. + +## Usage + + + ### With Radix Dialog + + A common use case is rendering Clerk components inside a Radix Dialog. Without ``, the `` popover would render outside the dialog and may not be interactable. + + ```tsx {{ filename: 'app/components/UserDialog.tsx' }} + 'use client' + + import { useRef } from 'react' + import * as Dialog from '@radix-ui/react-dialog' + import { UNSAFE_PortalProvider, UserButton } from '@clerk/nextjs' + + export function UserDialog() { + const containerRef = useRef(null) + + return ( + + Open Dialog + + + + containerRef.current}> + + + + + + ) + } + ``` + + + + ### With Reka UI Dialog + + ```vue {{ filename: 'UserDialog.vue' }} + + + ``` + + +## Properties + + + - `getContainer` + - `() => HTMLElement | null` + + A function that returns the container element where portals should be rendered. This function is called each time a portal needs to be rendered, so it should return a stable reference to the container element. + + --- + + - `children` + - `React.ReactNode` + + The Clerk components that should have their portals rendered into the custom container. +