or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-udecode--plate-node-id

Node ID plugin for Plate rich-text editor that automatically assigns unique identifiers to nodes

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@udecode/plate-node-id@49.0.x

To install, run

npx @tessl/cli install tessl/npm-udecode--plate-node-id@49.0.0

index.mddocs/

Plate Node ID Plugin

The Plate Node ID Plugin automatically assigns unique identifiers to nodes in a Plate rich-text editor. It enables features like drag & drop by ensuring each node has a unique ID, with configurable options for ID generation, filtering, and handling of duplicate IDs.

Package Information

  • Package Name: @udecode/plate-node-id
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @udecode/plate-node-id

Core Imports

import { NodeIdPlugin, type NodeIdConfig, withNodeId } from "@udecode/plate-node-id";

For CommonJS:

const { NodeIdPlugin, withNodeId } = require("@udecode/plate-node-id");

Basic Usage

import { createPlateEditor } from "@udecode/plate";
import { NodeIdPlugin } from "@udecode/plate-node-id";

// Add the plugin to your Plate editor
const editor = createPlateEditor({
  plugins: [
    NodeIdPlugin,
    // ... other plugins
  ],
});

// The plugin automatically assigns IDs to nodes as they're inserted
const nodeWithId = {
  type: "paragraph",
  children: [{ text: "Hello world" }],
  // id: "abc123" - automatically added by the plugin
};

Architecture

The Node ID Plugin follows Plate's plugin architecture with three main components:

  • Plugin Definition: NodeIdPlugin - Main plugin configuration that defines default options and normalization behavior
  • Editor Override: withNodeId - Transforms editor behavior to handle automatic ID assignment during insert operations
  • Configuration: NodeIdConfig - Comprehensive options for controlling ID generation, filtering, and deduplication logic

The plugin integrates with Slate.js transforms to intercept insert operations and automatically assign unique IDs while handling edge cases like undo/redo, copy/paste, and node splitting.

Capabilities

Plugin Configuration

Main plugin instance that provides Node ID functionality to Plate editor.

const NodeIdPlugin: SlatePlugin<NodeIdConfig>;

Editor Override Function

Editor override function that enables Node ID functionality by intercepting editor transforms.

const withNodeId: OverrideEditor<NodeIdConfig>;

Configuration Options

type NodeIdConfig = PluginConfig<
  'nodeId',
  {
    disableInsertOverrides?: boolean;
    filterInline?: boolean;
    filterText?: boolean;
    idKey?: string;
    normalizeInitialValue?: boolean;
    reuseId?: boolean;
    idCreator?: () => any;
  } & QueryNodeOptions
>;

Configuration Properties:

  • disableInsertOverrides?: boolean - By default, when a node inserted using editor.tf.insertNode(s) has an id, it will be used instead of the id generator, except if it already exists in the document. Set this option to true to disable this behavior. (default: undefined)
  • filterInline?: boolean - Filter inline Element nodes. (default: true)
  • filterText?: boolean - Filter Text nodes. (default: true)
  • idKey?: string - Node key to store the id. (default: 'id')
  • normalizeInitialValue?: boolean - Normalize initial value. If false, normalize only the first and last node are missing id. To disable this behavior, use NodeIdPlugin.configure({ normalizeInitialValue: null }). (default: false)
  • reuseId?: boolean - Reuse ids on undo/redo and copy/pasting if not existing in the document. This is disabled by default to avoid duplicate ids across documents. (default: false)
  • idCreator?: () => any - A function that generates and returns a unique ID. (default: () => nanoid(10))

Inherited from QueryNodeOptions:

  • allow?: QueryNodeOptions['allow'] - Node types to allow
  • exclude?: QueryNodeOptions['exclude'] - Node types to exclude
  • filter?: QueryNodeOptions['filter'] - Custom filter function for nodes

Usage Examples

Custom ID Generation

import { NodeIdPlugin } from "@udecode/plate-node-id";
import { v4 as uuidv4 } from "uuid";

const editor = createPlateEditor({
  plugins: [
    NodeIdPlugin.configure({
      options: {
        idCreator: () => uuidv4(), // Use UUID instead of nanoid
      },
    }),
  ],
});

Custom ID Key

import { NodeIdPlugin } from "@udecode/plate-node-id";

const editor = createPlateEditor({
  plugins: [
    NodeIdPlugin.configure({
      options: {
        idKey: "nodeId", // Store IDs in 'nodeId' instead of 'id'
      },
    }),
  ],
});

Including Text Nodes

import { NodeIdPlugin } from "@udecode/plate-node-id";

const editor = createPlateEditor({
  plugins: [
    NodeIdPlugin.configure({
      options: {
        filterText: false, // Assign IDs to text nodes as well
      },
    }),
  ],
});

Reusing IDs on Copy/Paste

import { NodeIdPlugin } from "@udecode/plate-node-id";

const editor = createPlateEditor({
  plugins: [
    NodeIdPlugin.configure({
      options: {
        reuseId: true, // Reuse existing IDs if not duplicated
      },
    }),
  ],
});

Normalizing Initial Value

import { NodeIdPlugin } from "@udecode/plate-node-id";

const editor = createPlateEditor({
  plugins: [
    NodeIdPlugin.configure({
      options: {
        normalizeInitialValue: true, // Add IDs to all nodes on initialization
      },
    }),
  ],
  value: [
    {
      type: "paragraph",
      children: [{ text: "This will get an ID" }],
      // No id property - will be automatically added
    },
  ],
});

Types

Core Plugin Types

Note: Types like PluginConfig, QueryNodeOptions, and NodeEntry are re-exported from @udecode/plate for convenience, but originally come from various Plate core packages.

// Core plugin type (derived from createTSlatePlugin return type)
type SlatePlugin<C extends AnyPluginConfig = PluginConfig> = {
  key: string;
  options: C;
  // ... other plugin properties
};

type OverrideEditor<TConfig = PluginConfig> = (params: {
  editor: PlateEditor;
  getOptions: () => TConfig;
  tf: EditorTransforms;
}) => Partial<PlateEditor>;

type PluginConfig<TKey = string, TOptions = {}> = {
  key: TKey;
} & TOptions;

interface QueryNodeOptions {
  allow?: string[] | string;
  exclude?: string[] | string;
  filter?: (nodeEntry: NodeEntry) => boolean;
}

Node Types

// Re-exported from @udecode/plate
type Descendant = Element | Text;
type NodeEntry<T = Node> = [T, Path];
interface NodeProps<T = {}> extends T {
  [key: string]: unknown;
}
type TNode = Element | Text;