---
productId: material-ui
title: React Portal component
components: Portal
githubLabel: 'scope: portal'
---

# Portal

The Portal component lets you render its children into a DOM node that exists outside of the Portal's own DOM hierarchy.

{{"component": "@mui/docs/ComponentLinkHeader", "design": false}}

## Introduction

Portal is a utility component built around [React's `createPortal()` API](https://react.dev/reference/react-dom/createPortal).
It gives you the functionality of `createPortal()` in a convenient component form.
It's used internally by the [Modal](/material-ui/react-modal/) and [Popper](/material-ui/react-popper/) components.

:::info
According to [the React docs](https://react.dev/reference/react-dom/createPortal), portals are useful when "you need the child element to visually 'break out' of its container"—for instance, modals and tooltips, which need to exist outside of the normal flow of the document.
:::

Normally, children of a component are rendered within that component's DOM tree.
But sometimes it's necessary to mount a child at a different location in the DOM.
The Portal component accepts a `container` prop that passes a `ref` to the DOM node where its children will be mounted.

The following demo shows how a `<span>` nested within a Portal can be appended to a node outside of the Portal's DOM hierarchy—click **Mount children** to see how it behaves:

```tsx
import * as React from 'react';
import Portal from '@mui/material/Portal';
import { Box } from '@mui/system';

export default function SimplePortal() {
  const [show, setShow] = React.useState(false);
  const container = React.useRef(null);

  const handleClick = () => {
    setShow(!show);
  };

  return (
    <div>
      <button type="button" onClick={handleClick}>
        {show ? 'Unmount children' : 'Mount children'}
      </button>
      <Box sx={{ p: 1, my: 1, border: '1px solid' }}>
        It looks like I will render here.
        {show ? (
          <Portal container={() => container.current!}>
            <span>But I actually render here!</span>
          </Portal>
        ) : null}
      </Box>
      <Box sx={{ p: 1, my: 1, border: '1px solid' }} ref={container} />
    </div>
  );
}

```

## Basics

### Import

```jsx
import Portal from '@mui/material/Portal';
```

## Customization

### Server-side Portals

The DOM API isn't available on the server, so you need to use the `container` prop callback.
This callback is called during a React layout effect:

```jsx
<Portal container={() => document.getElementById('filter-panel')!}>
  <Child />
</Portal>
```

:::error
The Portal component cannot be used to render child elements on the server—client-side hydration is necessary.
This is because React doesn't support the [`createPortal()` API](https://react.dev/reference/react-dom/createPortal) on the server.
See [this GitHub issue](https://github.com/facebook/react/issues/13097) for details.
:::


# Portal API

## Demos

For examples and details on the usage of this React component, visit the component demo pages:

- [Portal](https://deploy-preview-47558--material-ui.netlify.app/material-ui/react-portal/)

## Import

```jsx
import Portal from '@mui/material/Portal';
// or
import { Portal } from '@mui/material';
```

## Props

| Name | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| children | `node` | - | No |  |
| container | `HTML element \| func` | - | No |  |
| disablePortal | `bool` | `false` | No |  |

> **Note**: The `ref` is forwarded to the root element.

## Source code

If you did not find the information on this page, consider having a look at the implementation of the component for more detail.

- [/packages/mui-material/src/Portal/Portal.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/mui-material/src/Portal/Portal.tsx)