Simple Method to Block Copy and Paste in Monaco Editor with React
Tags: react, monacoeditor, javascript, webdev
Published: 2024-05-24 15:07:26

**[Monaco Editor](https://www.npmjs.com/package/@monaco-editor/react)**, the code editor that powers Visual Studio Code, is a powerful tool for developers, providing a rich set of features and customization options. However, there might be situations where you want to disable the copy-paste functionality, such as in coding assessments or educational tools to prevent cheating. In this blog, we will explore how to disable the copy-paste feature in Monaco Editor.

**Why Disable Copy-Paste?**
Before diving into the implementation, let’s discuss why you might want to disable copy-paste in a code editor:

1. **Academic Integrity:** In educational settings, to ensure students write their code from scratch during exams or practice sessions.
2. **Prevent Plagiarism:** To discourage copying code from other sources without understanding it.
3. **Skill Assessment:** To accurately assess a developer’s coding skills during interviews or coding challenges.


## **Step by step solution**
**Step 1: Setting Up Monaco Editor**
First, ensure you have Monaco Editor set up in your project. You can install it via npm:
```bash
npm install @monaco-editor/react
```
Include it in your project:
```javascript
import { Editor } from "@monaco-editor/react";
```
**Step 2: Configuring Editor Options**
To disable certain functionalities and customize the editor's behavior, configure its options. For instance, you can disable the context menu and set other useful preferences:

Here's list of options for editor: https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IStandaloneEditorConstructionOptions.html

```javascript
const options = {
  selectOnLineNumbers: true,
  mouseWheelZoom: true,
  fontSize: 18,
  contextmenu: false, // Disables right-click context menu
  formatOnType: true,
  smoothScrolling: true,
  wordWrap: "on",
};
```

**Step 3: Handling Key Down Events**
To detect and prevent copy-paste actions, add an event listener for key down events. This allows you to intercept the key combinations for copy (Ctrl/Cmd + C) and paste (Ctrl/Cmd + V):
```javascript
const onMount = (editor, monaco) => {
  editorRef.current = editor;
  editor.focus();

  editor.onKeyDown((event) => {
    const { keyCode, ctrlKey, metaKey } = event;
    if ((keyCode === 33 || keyCode === 52) && (metaKey || ctrlKey)) {
      event.preventDefault();
      setActivity("copypaste");
      setOpen(true);
    }
  });
};
```

**Step 4: Implementing the Modal Component**
The Modal component provides visual feedback to the user about their activities. Here's how to implement it:
```javascript
import React from "react";
import { IoIosCloseCircle } from "react-icons/io";
import { IoWarning } from "react-icons/io5";

export default function Modal({ activity, open, onClose }) {
  return (
    <div>
      <div
        className={`fixed inset-0 bg-gray-800 bg-opacity-80 z-50 transition-opacity ${
          open ? "opacity-100" : "opacity-0 pointer-events-none"
        }`}
      ></div>
      <div
        onClick={(e) => e.stopPropagation()}
        className={`fixed inset-0 flex justify-center items-center z-50 ${
          open ? "opacity-100" : "opacity-0 pointer-events-none"
        }`}
      >
        <div className="bg-white rounded-xl shadow p-6 relative">
          <button onClick={onClose} className="absolute top-2 right-2">
            <IoIosCloseCircle size={24} />
          </button>
          <div className="text-center w-full h-52 z-50 flex justify-center items-center flex-col gap-5">
            <div className="mx-auto my-4 w-full">
              <h3 className="text-lg font-black text-gray-800">
                {activity === "copypaste"
                  ? "Copy Paste Activity"
                  : "Handle any other activity here"}
              </h3>
              <p className="text-md text-gray-700 font-semibold">
                {activity === "copypaste"
                  ? "Copy paste activity has been notified to faculty"
                  : "Handle any other activity here"}
              </p>
              <p className="text-md text-gray-700 font-semibold">
                {activity === "copypaste"
                  ? "On Next copy paste your exam will be terminated"
                  : "Handle any other activity here"}
              </p>
            </div>
            <button
              className="text-white bg-red-500 p-3 rounded-lg w-full flex justify-center items-center gap-2"
              onClick={onClose}
            >
              {<IoWarning />} {activity === "copypaste" ? "Close Warning" : "Handle any other here"}
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}
```
## Full code for Editor Component:
```javascript
import React, { useState, useRef } from "react";
import { Editor } from "@monaco-editor/react";
import Modal from "../../../../components/Modal/Modal.jsx";

const EditorWindow = () => {
  const [activity, setActivity] = useState("");
  const [open, setOpen] = useState(false);

  const editorRef = useRef(null);

  const options = {
    selectOnLineNumbers: true,
    mouseWheelZoom: true,
    fontSize: 18,
    contextmenu: false,
    formatOnType: true,
    smoothScrolling: true,
    wordWrap: "on",
  };

  const onMount = (editor, monaco) => {
    editorRef.current = editor;
    editor.focus();

    editor.onKeyDown((event) => {
      const { keyCode, ctrlKey, metaKey } = event;
      if ((keyCode === 33 || keyCode === 52) && (metaKey || ctrlKey)) {
        event.preventDefault();
        setActivity("copypaste");
        setOpen(true);
  };

  return (
    <>
      <div>
        <Modal activity={activity} open={open} onClose={() => setOpen(false)} />
        <div className="overlay overflow-hidden w-full h-full shadow-4xl">
          <Editor
            height="85vh"
            width="100vw"
            theme="vs-dark"
            language="java"
            options={options}
            defaultValue="some default value for editor"
            onMount={onMount}
          />
        </div>
      </div>
    </>
  );
};

export default EditorWindow;
```

**Conclusion**
By following these steps, you can effectively disable copy-paste functionality in Monaco Editor and monitor user activities to ensure academic integrity. This approach is particularly useful in educational platforms and coding assessments where maintaining the originality of student work is crucial. By customizing and extending this implementation, you can adapt it to suit various educational and assessment platforms.