Skip to main content

A Guide to Building a Custom Web Based JSON Editor with Syntax Highlighting using react

Updated 5 min readMarkdown
A Guide to Building a Custom Web Based JSON Editor with Syntax Highlighting using react

Introduction

Building a JSON editor from scratch can be tough, but I'll give you a simple guide to create your own with custom syntax highlighting without using any thrid party plugins . Please be aware that this is only a guidance on how to accomplish this. I won't go into further detail about this .

What about HTML5 textarea ?

When it comes to creating a JSON editor, using only the HTML5 textarea is not suitable because it lacks support for injecting custom text highlighting and formatting.

Unlike specialized editors, a textarea is limited in its ability to provide a tailored experience for editing JSON data.

The idea

The idea is to use a textarea and a pre element. The textarea collects user inputs, and the pre element formats the text from the textarea. For effective syntax highlighting and formatting, it's important for the textarea and pre elements to overlap. We hide the text within the textarea, displaying only the content of the pre element. This ensures that the user's entered JSON data looks well formatted on the screen.

To achieve syntax highlighting, we can use a utility function that identifies the syntax type. this function can inject a span with a classname corresponding to the syntax type. Subsequently, we can utilize CSS to style the span, enhancing the visual presentation of the highlighted syntax.

Building the layout

As I mentioned above, we should use an overlapping text area and pre element to create the main layout.

Example code - layout

<div className="wrapper">
   <pre
      className="pre-wrapper"
      >
</pre>
   <textarea
      placeholder="please input JSON"
      wrap="off"
      className="json-input"
      spellCheck={false}
      />
</div>

Styling guide

The wrapper div should be positioned relative, and the pre element and text area should be positioned absolute ( overlap ) . We should use the same line height, font size, and font family for both the text area and the pre element. then we need to set the text area text colour to transparent.

Example css code to get an idea

.wrapper {
  border-left: 1px solid #ccc;
  margin: 0;
  position: relative;
  font-family: monospace;
  overflow: auto;
  height: 20rem;
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
  flex: 1;
}

.json-input {
  z-index: 1;
  position: absolute;
  min-width: 100%;
  min-height: 100%;
  height: auto;
  margin: 0;
  appearance: none;
  resize: none;
  border: none;
  outline: none;
  font-family: monospace !important;
  display: inline;
  overflow: hidden;
  padding: 0.5rem;
  box-sizing: border-box;
  color: transparent;
  background: transparent;
  caret-color: rgb(0, 0, 0);
}

pre {
  z-index: 3;
  margin: 0;
  pointer-events: none;
  position: absolute;
  overflow: auto;
  height: auto;
  min-width: 100%;
  width: auto;
  scrollbar-width: none;
  padding: 0.5rem;
  box-sizing: border-box;
}

.json-input,
pre,
pre * {
  font-size: 0.8rem;
  font-family: monospace;
  line-height: 1rem;
  box-sizing: border-box;
}

Once the layout is set up, it's essential to store the user-input JSON in the React state. This can be achieved by incorporating an onChange event on the textarea and invoking a function, such as handleJSONInputChange, which updates the state based on the user input.

 <textarea
   value={userJSON}
   onChange={handleJSONInputChange} />

How to do the syntax highlighting

the basic idea is to create a utility function for this . which takes a JSON string as input and returns an HTML formatted string with syntax highlighting. Here's how it works

  1. Special Characters: We start by replacing special characters like "&", "<", and ">" with codes that won't cause issues when displaying on a webpage. This helps to avoid any code injections.

  2. Identifying Elements: The function then looks at different parts of the JSON, like string, numbers, boolean values, and null values. It uses a set of rules (regular expressions) to figure out what each part is.

  3. Styling: After figuring out what each part is, the function wraps them in div element and adds styles to them using CSS classes. This makes each type of information look different, so you can easily tell them apart.

  4. Result: The end result is an HTML formatted string that highlights different types of information in the JSON. This makes it much easier for people to read and understand the data when it's displayed on a webpage.

Example code to get an idea

export function syntaxHighlight(json) {
  if (!json) return '';

  json = json
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');
  return json.replace(
    /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g,
    function (match) {
      var cls = 'number';
      if (/^"/.test(match)) {
        if (/:$/.test(match)) {
          cls = 'key';
        } else {
          cls = 'string';
        }
      } else if (/true|false/.test(match)) {
        cls = 'boolean';
      } else if (/null/.test(match)) {
        cls = 'null';
      }
      return '<div class="' + cls + '">' + match + '</div>';
    }
  );
}

Displaying the Highlighted code

To display the highlighted code, we need to inject the modified JSON data into the pre element. We can use dangerouslySetInnerHTML for that.

Please note that when injecting something into the dom it's better to sanitize it to avoid any code injections done by malicious guys.

<pre
ref={preRef}
className="line-numbered-pre"
dangerouslySetInnerHTML={{
__html: syntaxHighlight(userJSON),
}}
></pre>

The Demo

This demo has more features that I have implemented. You can also add more features, like line numbers.

Conclusion

In this article, I gave you a guide to creating a custom JSON editor. This is not a full step by step tutorial.

the purpose of this article is to give you a basic idea of how this works.

Feel free to research , customize and extend your editor based on your specific needs. The world of web development is dynamic, and having tools that adapt to your workflow is key to staying productive. Happy coding!

About the author

  • working on the front end to build fantastic user interfaces and deliver a top notch user experience.

No comments yet. Be the first to comment.