javascriptcopyclipboardcopy-pastenavigator

Copy HTML/rich text using JS navigator.clipboard


Based on Clipboard Write API specification I could copy to clipboard like below:

    const type = "text/plain";
    const text = "test plain";
    const blob = new Blob([text], { type });
    const data = [new ClipboardItem({ [type]: blob })];

    navigator.clipboard.write(data).then(
        () => {alert('success plain copy')},
        () => {}
    );

I tried that and that worked. But I tried to change the type to HTML or rich text like below:

    const type = "text/html"
    const text = "<b>text html</b>";
    const blob = new Blob([text], { type });
    const data = [new ClipboardItem({ [type]: blob })];

    navigator.clipboard.write(data).then(
        () => {alert('success html copy')},
        () => {}
    );

And it doesn't work. The success alert is shown up, but the HTML text is not copied.

I have conducted online research and based on my findings, my code appears to be correct. However, it is puzzling why it is not functioning as intended.

By the way, actually I want to create a SO snippet, but the permission is blocked, so if others want to try my codes, you check on jsfiddle


Solution

  • I found an article that solved the problem.

    I just realized, if I need to add both text/plain and text/html to ClipboardItem object. Maybe text/plain is required to allow system paste as plain (cmd/ctrl+shift+v).

    Here is the correct code:

    const originalText = "Original Text"
    const boldText = "<b>"+originalText+"</b>";
    const blobHtml = new Blob([boldText], { type: "text/html" });
    const blobText = new Blob([originalText], { type: "text/plain" });
    const data = [new ClipboardItem({
        ["text/plain"]: blobText,
        ["text/html"]: blobHtml,
    })];
    
    navigator.clipboard.write(data).then(
        () => {alert('success html copy')},
        () => {}
    );
    

    You can check the worked demo on jsfiddle