Skip to main content

Wormhole/Portal

Both Ember.js and React allow rendering content outside the normal component tree hierarchy. This "portal" pattern is used for modals, tooltips, and dropdowns that need to get out of their container's styling constraints. The pattern is useful for avoiding overflow issues with modals and their parent dom nodes.

In Ember, use the built-in {{in-element}} helper (v3.20+) or the ember-wormhole addon for older versions (doc). React provides createPortal() as a core API (doc).

Ember

Modern approach (v3.20+) - Built-in {{in-element}} helper:

{{#in-element this.destinationElement}}
<div>Hello cheatsheet!</div>
{{/in-element}}
// Component class
export default class MyComponent extends Component {
destinationElement = document.getElementById('modal-root'); // destination would be an id here of modal
}

Legacy approach - ember-wormhole addon:

{{#ember-wormhole to="modal-root"}}
Hello cheatsheet!
{{/ember-wormhole}}

React

Basic usage - createPortal() from react-dom:

import { createPortal } from 'react-dom';

function PortalHello() {
return createPortal(
<div>Hello cheatsheet!</div>,
document.getElementById('modal-root') // destination would be an id here
);
}

Modal example with conditional rendering:

function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null;

return createPortal(
<div className="modal-backdrop" onClick={onClose}>
<div className="modal-content" onClick={e => e.stopPropagation()}>
{children}
</div>
</div>,
document.body // adds destination of the body of the whole document
);
}

Further notes

  • Ember ember-elsewhere addon is an alternative to {{in-element}} and ember-wormhole