Skip to content


Provides context for nested floating elements when they are not children of each other on the DOM.

If your elements are not portalled into a common node (e.g. FloatingPortal), then the natural DOM tree hierarchy renders this unnecessary.

A nested floating element may look like the following, where there is a popover inside the content of another one:

import {FloatingTree} from '@floating-ui/react-dom-interactions';
function App() {
  return (
        render={() => (
          <Popover render={() => 'Nested Popover'}>


The following creates an infinitely nestable <Popover /> component. Usage of this component must be wrapped within a single <FloatingTree /> component as seen in the previous code snippet:

function Popover({children}) {
  // Subscribe this component to the <FloatingTree />
  const nodeId = useFloatingNodeId();
  // Pass the subscribed `nodeId` to useFloating()
  // Wrap the rendered elements in a `<FloatingNode />`,
  // passing in the subscribed `nodeId`
  return (
    <FloatingNode id={nodeId}>
      {/* reference element */}
        {open && /* floating element */}


  • useFloatingNodeId() subscribes the component to the tree context. Call this only once as it has side effects.
  • useFloatingParentNodeId() returns the parent FloatingNode id, if it exists. This will be null for roots (not nested).
  • useFloatingTree() for accessing the tree object, which includes an event emitter to communicate across the tree components (events).
interface FloatingTreeType {
  nodesRef: React.MutableRefObject<Array<FloatingNodeType>>;
  events: FloatingEvents;
  addNode: (node: FloatingNodeType) => void;
  removeNode: (node: FloatingNodeType) => void;

FloatingTree wrapper

You can use the following technique to avoid having the consumer specify the <FloatingTree /> wrapper:

function PopoverComponent() {
  // Main logic as seen earlier
// This is the component the consumer uses
export function Popover(props) {
  const parentId = useFloatingParentNodeId();
  // This is a root, so we wrap it with the tree
  if (parentId === null) {
    return (
        <PopoverComponent {...props} />
  return <PopoverComponent {...props} />;