Skip to content

Portal

Size
0.29 kb
View source

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

  1. Define the Portal component.

    Use the defaultRoots option to specify the default container for the portal.
    If omitted or no root is found, the children are rendered in the body.

    Set spa to true 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 body
    defaultRoots: ['dialog', '#root'],
    // Set to true to render immediately on the client
    spa: true,
    })
  2. 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>
    )
    }
  3. 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.

Optionsdescription
defaultRootsAn 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.
spaSet 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.

Propsdescription
rootA 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.
childrenThe content to be rendered in the portal.