Comment/discussion IDs retained when copying between editors #5092
Comment/discussion IDs retained when copying between editorsHey ! I'm using PlateJS comments/discussions and noticed that when content containing comments is copied from one Slate/Plate document and pasted into another, the original As a result, resolving the copied comment in the new document also resolves the original comment in the source document. Expected: When copying between independent documents, source-specific comment/discussion references should either be removed or remapped to new IDs. Is there an official/recommended way in Plate to strip or remap comment/discussion metadata during copy/paste? Is there an existing issue or implementation for this? Thanks! |
Replies: 1 comment 1 reply
|
This happens because Plate/Slate's clipboard payload is a serialized fragment, not a document-aware copy operation. Plate stores a comment reference on text leaves as For independent documents, the safest default is to strip the source references before insertion. Plate v53 exposes a import {
createSlatePlugin,
TextApi,
type Descendant,
} from 'platejs';
const isCommentRef = (key: string) =>
key === 'comment' ||
key === 'commentId' ||
key === 'discussionId' ||
key === 'commentTransient' ||
key.startsWith('comment_');
const stripCommentRefs = (fragment: Descendant[]): Descendant[] => {
const visit = (node: Descendant): Descendant => {
const clean = Object.fromEntries(
Object.entries(node).filter(([key]) => !isCommentRef(key))
) as any;
if (!TextApi.isText(node)) {
clean.children = node.children.map(visit);
}
return clean;
};
return fragment.map(visit);
};
export const StripCrossDocumentCommentsPlugin = createSlatePlugin({
key: 'strip-cross-document-comments',
editOnly: true,
inject: {
plugins: {
ast: {
parser: {
transformFragment: ({ fragment }) => stripCommentRefs(fragment),
},
},
},
},
});Add that plugin to the destination editor's plugin list. It preserves text, elements, and unrelated marks, but removes Plate's Test this through If same-document copies should preserve comments, add an application-owned document UUID in a custom MIME payload and run the strip only when source UUID differs. To remap instead, that payload must also carry or reference the source discussion records; generate one old→new ID map, rewrite every |
This happens because Plate/Slate's clipboard payload is a serialized fragment, not a document-aware copy operation. Plate stores a comment reference on text leaves as
comment_<id>(source); the genericapplication/x-slate-fragmentpath copies those properties unchanged. It has no source/destination document identity and does not carry yourTDiscussionstore, so it cannot safely decide whether to preserve or remap the ID.For independent documents, the safest default is to strip the source references before insertion. Plate v53 exposes a
parser.transformFragmenthook after the Slate fragment is decoded and beforeinsertFragment(pipeline):