Node ID plugin for Plate rich-text editor that automatically assigns unique identifiers to nodes
npx @tessl/cli install tessl/npm-udecode--plate-node-id@49.0.00
# Plate Node ID Plugin
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: @udecode/plate-node-id
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @udecode/plate-node-id`
10
11
## Core Imports
12
13
```typescript
14
import { NodeIdPlugin, type NodeIdConfig, withNodeId } from "@udecode/plate-node-id";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { NodeIdPlugin, withNodeId } = require("@udecode/plate-node-id");
21
```
22
23
## Basic Usage
24
25
```typescript
26
import { createPlateEditor } from "@udecode/plate";
27
import { NodeIdPlugin } from "@udecode/plate-node-id";
28
29
// Add the plugin to your Plate editor
30
const editor = createPlateEditor({
31
plugins: [
32
NodeIdPlugin,
33
// ... other plugins
34
],
35
});
36
37
// The plugin automatically assigns IDs to nodes as they're inserted
38
const nodeWithId = {
39
type: "paragraph",
40
children: [{ text: "Hello world" }],
41
// id: "abc123" - automatically added by the plugin
42
};
43
```
44
45
## Architecture
46
47
The Node ID Plugin follows Plate's plugin architecture with three main components:
48
49
- **Plugin Definition**: `NodeIdPlugin` - Main plugin configuration that defines default options and normalization behavior
50
- **Editor Override**: `withNodeId` - Transforms editor behavior to handle automatic ID assignment during insert operations
51
- **Configuration**: `NodeIdConfig` - Comprehensive options for controlling ID generation, filtering, and deduplication logic
52
53
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.
54
55
## Capabilities
56
57
### Plugin Configuration
58
59
Main plugin instance that provides Node ID functionality to Plate editor.
60
61
```typescript { .api }
62
const NodeIdPlugin: SlatePlugin<NodeIdConfig>;
63
```
64
65
### Editor Override Function
66
67
Editor override function that enables Node ID functionality by intercepting editor transforms.
68
69
```typescript { .api }
70
const withNodeId: OverrideEditor<NodeIdConfig>;
71
```
72
73
### Configuration Options
74
75
```typescript { .api }
76
type NodeIdConfig = PluginConfig<
77
'nodeId',
78
{
79
disableInsertOverrides?: boolean;
80
filterInline?: boolean;
81
filterText?: boolean;
82
idKey?: string;
83
normalizeInitialValue?: boolean;
84
reuseId?: boolean;
85
idCreator?: () => any;
86
} & QueryNodeOptions
87
>;
88
```
89
90
**Configuration Properties:**
91
92
- `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)*
93
- `filterInline?: boolean` - Filter inline Element nodes. *(default: true)*
94
- `filterText?: boolean` - Filter Text nodes. *(default: true)*
95
- `idKey?: string` - Node key to store the id. *(default: 'id')*
96
- `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)*
97
- `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)*
98
- `idCreator?: () => any` - A function that generates and returns a unique ID. *(default: () => nanoid(10))*
99
100
**Inherited from QueryNodeOptions:**
101
- `allow?: QueryNodeOptions['allow']` - Node types to allow
102
- `exclude?: QueryNodeOptions['exclude']` - Node types to exclude
103
- `filter?: QueryNodeOptions['filter']` - Custom filter function for nodes
104
105
### Usage Examples
106
107
#### Custom ID Generation
108
109
```typescript
110
import { NodeIdPlugin } from "@udecode/plate-node-id";
111
import { v4 as uuidv4 } from "uuid";
112
113
const editor = createPlateEditor({
114
plugins: [
115
NodeIdPlugin.configure({
116
options: {
117
idCreator: () => uuidv4(), // Use UUID instead of nanoid
118
},
119
}),
120
],
121
});
122
```
123
124
#### Custom ID Key
125
126
```typescript
127
import { NodeIdPlugin } from "@udecode/plate-node-id";
128
129
const editor = createPlateEditor({
130
plugins: [
131
NodeIdPlugin.configure({
132
options: {
133
idKey: "nodeId", // Store IDs in 'nodeId' instead of 'id'
134
},
135
}),
136
],
137
});
138
```
139
140
#### Including Text Nodes
141
142
```typescript
143
import { NodeIdPlugin } from "@udecode/plate-node-id";
144
145
const editor = createPlateEditor({
146
plugins: [
147
NodeIdPlugin.configure({
148
options: {
149
filterText: false, // Assign IDs to text nodes as well
150
},
151
}),
152
],
153
});
154
```
155
156
#### Reusing IDs on Copy/Paste
157
158
```typescript
159
import { NodeIdPlugin } from "@udecode/plate-node-id";
160
161
const editor = createPlateEditor({
162
plugins: [
163
NodeIdPlugin.configure({
164
options: {
165
reuseId: true, // Reuse existing IDs if not duplicated
166
},
167
}),
168
],
169
});
170
```
171
172
#### Normalizing Initial Value
173
174
```typescript
175
import { NodeIdPlugin } from "@udecode/plate-node-id";
176
177
const editor = createPlateEditor({
178
plugins: [
179
NodeIdPlugin.configure({
180
options: {
181
normalizeInitialValue: true, // Add IDs to all nodes on initialization
182
},
183
}),
184
],
185
value: [
186
{
187
type: "paragraph",
188
children: [{ text: "This will get an ID" }],
189
// No id property - will be automatically added
190
},
191
],
192
});
193
```
194
195
## Types
196
197
### Core Plugin Types
198
199
Note: Types like `PluginConfig`, `QueryNodeOptions`, and `NodeEntry` are re-exported from `@udecode/plate` for convenience, but originally come from various Plate core packages.
200
201
```typescript { .api }
202
// Core plugin type (derived from createTSlatePlugin return type)
203
type SlatePlugin<C extends AnyPluginConfig = PluginConfig> = {
204
key: string;
205
options: C;
206
// ... other plugin properties
207
};
208
209
type OverrideEditor<TConfig = PluginConfig> = (params: {
210
editor: PlateEditor;
211
getOptions: () => TConfig;
212
tf: EditorTransforms;
213
}) => Partial<PlateEditor>;
214
215
type PluginConfig<TKey = string, TOptions = {}> = {
216
key: TKey;
217
} & TOptions;
218
219
interface QueryNodeOptions {
220
allow?: string[] | string;
221
exclude?: string[] | string;
222
filter?: (nodeEntry: NodeEntry) => boolean;
223
}
224
```
225
226
### Node Types
227
228
```typescript { .api }
229
// Re-exported from @udecode/plate
230
type Descendant = Element | Text;
231
type NodeEntry<T = Node> = [T, Path];
232
interface NodeProps<T = {}> extends T {
233
[key: string]: unknown;
234
}
235
type TNode = Element | Text;
236
```