Portal
A utility to create dynamic React portals with support for fallback roots and SSR handling.
The definePortal
function helps create a customizable Portal
component that renders its children into a specified DOM node (root). You can provide fallback roots and enable SPA-specific behavior for client-side rendering.
Features
- Flexible Default Roots: Renders content in a specified root, with fallback options. If no roots are found, it defaults to the body, ensuring compatibility across different DOM structures.
- SSR Compatibility: Avoid hydration errors by only executing on the client.
- SPA Optimization: With the
spa
option enabled, the portal renders content immediately on the client, enhancing responsiveness in Single Page Applications.
Quick Start
-
Define the
Portal
component.Use the
defaultRoots
option to specify the default container for the portal.
If omitted or no root is found, thechildren
are rendered in thebody
.Set
spa
totrue
if server-side rendering (SSR) is not needed. This way, the portal will render its children immediately on the client.portal.tsx 'use client'import { definePortal } from 'crustack/portal'export const { Portal } = definePortal({// Try to render in a <dialog> element if any, otherwise in #root, or fallback to the bodydefaultRoots: ['dialog', '#root'],// Set to true to render immediately on the clientspa: true,}) -
Wrap your component in the
Portal
.
The content will be dynamically inserted into the specified DOM node or the default root.import { Portal } from './portal'export function MyComponent() {return (<Portal><div>This content will render in the first available default root</div></Portal>)} -
Use a custom root element for this portal:
import { Portal } from './portal'export function MyComponent() {return (<Portal root='#root-element'><Portal><div>This content will render in the first available default root</div></Portal>)}
API Reference
definePortal
Create a custom Portal
component.
Options | description |
---|---|
defaultRoots | An array of roots to attempt rendering the portal. These can be CSS selectors or DOM elements. If no root is defined on the Portal component, the first available defaultRoot is used, otherwise it falls back to document.body . |
spa | Set to true to render immediately on the client side, skipping server-side rendering checks. |
Portal
The component returned by definePortal
. It renders its children into the specified root.
Props | description |
---|---|
root | A specific root element to render the children into. If not provided, the portal uses the default roots specified in defaultRoots , otherwise it falls back to document.body . |
children | The content to be rendered in the portal. |