Utilities
Installation
CLI
npx shadcn@latest add "https://diceui.com/r/portal"
pnpm dlx shadcn@latest add "https://diceui.com/r/portal"
yarn dlx shadcn@latest add "https://diceui.com/r/portal"
bun x shadcn@latest add "https://diceui.com/r/portal"
Manual
Install the following dependencies:
npm install @radix-ui/react-slot
pnpm add @radix-ui/react-slot
yarn add @radix-ui/react-slot
bun add @radix-ui/react-slot
Copy and paste the following code into your project.
"use client";
import { Slot, type SlotProps } from "@radix-ui/react-slot";
import * as React from "react";
import * as ReactDOM from "react-dom";
interface PortalProps extends SlotProps {
container?: Element | DocumentFragment | null;
}
function Portal(props: PortalProps) {
const { container: containerProp, ...portalProps } = props;
const [mounted, setMounted] = React.useState(false);
React.useLayoutEffect(() => {
setMounted(true);
}, []);
const container =
containerProp ?? (mounted ? globalThis.document?.body : null);
if (!container) return null;
return ReactDOM.createPortal(<Slot {...portalProps} />, container);
}
export { Portal };
export type { PortalProps };
Usage
import { Portal } from "@/components/portal"
export default function App() {
return (
<Portal>
{/* Content to be rendered in a different part of the DOM */}
<div>This will be rendered in the document body by default</div>
</Portal>
)
}
Custom Container
Specify a target container for portal rendering:
import { Portal } from "@/components/portal"
export default function App() {
const containerRef = useRef<HTMLDivElement>(null)
return (
<>
<div ref={containerRef} />
<Portal container={containerRef.current}>
<div>This will be rendered in the custom container</div>
</Portal>
</>
)
}
API Reference
Portal
A component that renders its children into a different part of the DOM tree using React's createPortal
.
Props
Prop | Type | Default |
---|---|---|
asChild? | boolean | false |
container? | Element | DocumentFragment | null | document.body |