# react-portal

> To make your life with React Portals easier.

Latest version **4.3.0** (published 2025-01-29) · MIT license · 0 weekly downloads

## Install

```sh
npm install react-portal
pnpm add react-portal
yarn add react-portal
bun add react-portal
```

## Health

**Score 38/100 (D)** — status: maintenance-mode.

Positive: has types package; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

Negative: stale; low maintenance score.

## Facts

| | |
|---|---|
| Version | 4.3.0 |
| Published | 2025-01-29 |
| First published | 2015-03-10 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | separate (@types/react-portal) |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 38.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 2152 |
| Author | Vojtech Miksu |
| Maintainers | miksu |
| Keywords | react, react-component, modal, lightbox, react-portal, portal, transportation |

## Links

- npm: https://www.npmjs.com/package/react-portal
- Repository: https://github.com/tajo/react-portal
- Homepage: https://github.com/tajo/react-portal#readme
- Issues: https://github.com/tajo/react-portal/issues
- npm.io page: https://npm.io/package/react-portal

## Dependencies (1)

- [prop-types](https://npm.io/package/prop-types.md) ^15.5.8

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 4.3.0 (latest) — 2025-01-29
- 4.0.0-rc.0 (next) — 2017-10-21
- 4.2.2 — 2022-03-30
- 4.2.1 — 2020-01-27
- 4.2.0 — 2018-11-27
- 4.1.5 — 2018-04-13
- 4.1.4 — 2018-03-21
- 4.1.3 — 2018-02-28
- 4.1.2 — 2017-12-19
- 4.1.1 — 2017-12-17
- 4.1.0 — 2017-12-07
- 4.0.0 — 2017-11-01
- 3.2.0 — 2017-10-19
- 4.0.0-beta.3 — 2017-10-18
- 4.0.0-beta.2 — 2017-10-04
- … 37 more at https://npm.io/package/react-portal/versions

## README

React-portal
============
[![npm version](https://img.shields.io/npm/v/react-portal.svg?style=flat-square)](https://www.npmjs.com/package/react-portal)
[![npm downloads](https://img.shields.io/npm/dm/react-portal.svg?style=flat-square)](https://www.npmjs.com/package/react-portal)
[![Build Status](https://travis-ci.org/tajo/react-portal.svg?branch=master)](https://travis-ci.org/tajo/react-portal)

> Struggling with modals, lightboxes or loading bars in React? React-portal creates a new top-level React tree and injects its children into it. That's necessary for proper styling (especially positioning).

*Looking for v3 documentation? Go [here](READMEv3.MD).*

## Features

- **uses React v16 and its official API for creating portals**
- **has a fallback for React v15**
- transports its children into a new React Portal which is appended by default to **document.body**
- can target user specified DOM element
- supports server-side rendering
- supports returning arrays (no wrapper divs needed)
- `<Portal />` and `<PortalWithState />` so there is no compromise between flexibility and convenience
- doesn't produce any DOM mess
- provides **close on ESC** and **close on outside mouse click** out of the box
- **no dependencies**, minimalistic

## Installation

```shell
yarn add react react-dom react-portal
```

## Usage

### Portal

```jsx 
import { Portal } from 'react-portal';

<Portal>
  This text is portaled at the end of document.body!
</Portal>

<Portal node={document && document.getElementById('san-francisco')}>
  This text is portaled into San Francisco!
</Portal>
```

That's it! Do you want to toggle portal? It's a plain React component, so you can simply do:

```jsx
{isOpen && <Portal>Sometimes portaled?</Portal>}
```

  **This gives you absolute flexibility and control** and I would recommend you to use it as a basic building block for your components like modals or notifications. **This code also works with server-side rendering**. If you think about just using official `ReactDOM.createPortal()`, you would have to check for existence of DOM environment.

React-portal used to come packed with some extra goodies because sometimes **you are ok with giving up some flexibility for convenience**. For that case, V4 introduces another component that handles its own state for you:

### PortalWithState

```jsx 
import { PortalWithState } from 'react-portal';

<PortalWithState closeOnOutsideClick closeOnEsc>
  {({ openPortal, closePortal, isOpen, portal }) => (
    <React.Fragment>
      <button onClick={openPortal}>
        Open Portal
      </button>
      {portal(
        <p>
          This is more advanced Portal. It handles its own state.{' '}
          <button onClick={closePortal}>Close me!</button>, hit ESC or
          click outside of me.
        </p>
      )}
    </React.Fragment>
  )}
</PortalWithState>
```

Don't let this example intimidate you! `PortalWithState` **expects one child, a function**. This function gets a few parameters (mostly functions) and returns a React component.

### There are 4 optional parameters:

- **openPortal** - function that you can call to open the portal
- **closePortal** - function that you can call to close the portal
- **portal** - the part of component that should be portaled needs to be wrapped by this function
- **isOpen** - boolean, tells you if portal is open/closed

### `<PortalWithState />` accepts this optional props:

- **node** - same as `<Portal>`, you can target a custom DOM element
- **closeOnOutsideClick** - boolean, portal closes when you click outside of it
- **closeOnEsc** - boolean, portal closes when the ESC key is hit 
- **defaultOpen** - boolean, the starting state of portal is being open
- **onOpen** - function, will get triggered after portal is open
- **onClose** - function, will get triggered after portal is closed

Also notice, that **the example returns a [Fragment](https://reactjs.org/docs/fragments.html) since React 16.2 supports it**! You can also return:
- an array - available from React v16, remember to add `key` attribute
- regular component - the example would be wrapped by a div, not a fragment

If you start running into limits of `<PortalWithState />` (complex animations), you probably want to use `<Portal />` instead and build a component tailored to your specific taste.

## Run Examples

```shell
git clone https://github.com/tajo/react-portal
cd react-portal
yarn install
yarn build:examples
open examples/index.html
```

## Contributions Welcome!

```shell
git clone https://github.com/tajo/react-portal
cd react-portal
yarn install
yarn build:examples --watch
open examples/index.html
```

### Run Tests

```
yarn test
```

## Author

Vojtech Miksu 2017, [miksu.cz](https://miksu.cz), [@vmiksu](https://twitter.com/vmiksu)

---
_Source: https://npm.io/package/react-portal · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
