ReactPortal type in TipTap source code

In this article, we will review the ReactPortal type in TipTap source code.

The below code is picked from tiptap/packages/react/src/Editor.js

import { Editor } from '@tiptap/core'
import { ReactPortal } from 'react'

import { ReactRenderer } from './ReactRenderer.js'

export type EditorWithContentComponent = Editor & { contentComponent?: ContentComponent | null }
export type ContentComponent = {
  setRenderer(id: string, renderer: ReactRenderer): void;
  removeRenderer(id: string): void;
  subscribe: (callback: () => void) => () => void;
  getSnapshot: () => Record<string, ReactPortal>;
  getServerSnapshot: () => Record<string, ReactPortal>;
}

ReactPortal is used as a type here in getSnapshot. This getSnapshot function is supposed to return a value of type Record<string, ReactPortal>. Similar declaration is found for getServerSnapshot.

I have seen this “portal” related code in the wild before but I could not recall. When I googled “Portal in React”, I found createPortal in React documentation.

But is createPortal related to ReactPortal type? what is createPortal anyway? createPortal lets you render some children into a different part of the DOM.

Below is a simple example picked from React docs.

import { createPortal } from 'react-dom';

export default function MyComponent() {
  return (
    <div style={{ border: '2px solid black' }}>
      <p>This child is placed in the parent div.</p>
      {createPortal(
        <p>This child is placed in the document body.</p>,
        document.body
      )}
    </div>
  );
}

I liked this example related to showing modal more.

I really was hoping to find that this function returns a value of type ReactPortal. I mean, it’s got matching word “Portal” but to my surprise, in the documentation it is mentioned that createPortal returns a value of type, ReactNode.

It is also worth mentioning that createPortal is imported from react-dom, whereas ReactPortal is imported from react. createPortal is a function and ReactPortal is a type.

About me:

Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.

I am open to work on interesting projects. Send me an email at

My Github — https://github.com/ramu-narasinga

My website — https://ramunarasinga.com

My Youtube channel — https://www.youtube.com/@thinkthroo

Learning platform — https://thinkthroo.com

Codebase Architecture — https://app.thinkthroo.com/architecture

Best practices — https://app.thinkthroo.com/best-practices

Production-grade projects — https://app.thinkthroo.com/production-grade-projects

References:

  1. https://github.com/ueberdosis/tiptap/blob/develop/packages/react/src/Editor.ts#L2

  2. https://react.dev/reference/react-dom/createPortal

  3. https://react.dev/reference/react-dom/createPortal#rendering-a-modal-dialog-with-a-portal

  4. https://react.dev/reference/react-dom/createPortal#returns