Posted on: 19/09/2026(updated)
The createPortal API is part of the React DOM. It lets you render some children of a React component in another part of the DOM.
Useful when you need to create UIs such as tooltips, toasts, modals and popups.
To create a portal, call createPortal, passing some JSX, and the DOM node where it should be rendered.
import { createPortal } from 'react-dom';
// ...
<div>
<p>This child is placed in the parent div.</p>
{createPortal(
<p>This child is placed in the document body.</p>,
document.body
)}
</div>
Normally, a React component and its children have a parent-child relationship, and all of the children are nested within their parent after rendering.
However, with the createPortal API, a React component can render all or some of its children in another location in the DOM.
A portal only changes the physical placement of the DOM node. In every other way, the JSX you render into a portal acts as a child node of the React component that renders it.
document.getElementById(). The node must already exist.key a unique string or number to be used as the portal's keycreatePortal returns a React node that can be included into JSX or returned from a React component. If React encounters it in the render output, it will placed the provided children inside the provided domNode.
import { createPortal } from 'react-dom';
function MyComponent() {
return (
<div style={{ border: '2px solid black' }}>
<p>This child is placed in the parent div.</p>
{createPortal(
<p>This child is placed in the document body.</p>,
document.body
)}
</div>
);
}
React will put the DOM nodes for the JSX you passed inside of the DOM node provided.
import React, { useState } from "react";
import { createPortal } from "react-dom";
function Modal({ onClose }) {
return createPortal(
<div className="modal">
<p>This is a modal.</p>
<button onClick={onClose}>Close</button>
</div>,
document.body,
);
}
function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(true)}>Open Modal</button>
{isOpen && <Modal onClose={() => setIsOpen(false)} />}
</div>
);
}
To achieve accessibility, use ARIA roles and attributes.
function Modal({ onClose }) {
return createPortal(
<div role="dialog" aria-modal="true" className="modal">
<p>This is a modal.</p>
<button onClick={onClose}>Close</button>
</div>,
document.body,
);
}
overflow:hidden or positioned incorrectly due to z-index issues.