Build a Simple React JavaScript Interactive Interactive Text-Based Code Highlighting App: A Beginner’s Guide

In the world of web development, readability is king. Whether you’re a seasoned developer or just starting, quickly understanding and navigating code is crucial. Imagine staring at a wall of text, struggling to pick out keywords, comments, and different data types. Frustrating, right? This is where code highlighting comes in. It transforms plain text code into a visually appealing and easily digestible format by applying different colors and styles to various elements. In this tutorial, we’ll build a simple, interactive code highlighting app using React. This app will allow users to paste code, and see it highlighted in real-time. This project will not only improve your React skills but also provide a practical tool for anyone who works with code.

Why Build a Code Highlighting App?

Code highlighting enhances the developer experience significantly. Here’s why building this app is beneficial:

  • Improved Readability: Color-coding different code elements (keywords, strings, comments, etc.) makes code easier to scan and understand.
  • Error Detection: Highlighting syntax errors visually helps catch mistakes early.
  • Learning Tool: Seeing code highlighted can help beginners learn the syntax and structure of programming languages.
  • Practical Application: This app can be used to quickly format and share code snippets in emails, documentation, or blog posts.
  • React Practice: It’s a great project for practicing React components, state management, and event handling.

This tutorial is designed for beginners and intermediate developers. We’ll break down the process step-by-step, explaining each concept in simple terms with plenty of code examples.

Project Setup and Prerequisites

Before we dive into the code, let’s make sure you have everything you need:

  • Node.js and npm (or yarn): You’ll need Node.js and npm (Node Package Manager) or yarn installed on your machine. You can download them from https://nodejs.org/.
  • Code Editor: A code editor like Visual Studio Code, Sublime Text, or Atom.
  • Basic Knowledge of HTML, CSS, and JavaScript: Familiarity with these languages is necessary to understand the concepts.

Let’s create a new React project using Create React App. Open your terminal and run the following command:

npx create-react-app code-highlighter-app

This command creates a new directory called `code-highlighter-app` with the basic structure of a React application. Navigate into the project directory:

cd code-highlighter-app

Now, start the development server:

npm start

This will open your app in your browser at `http://localhost:3000/`. You should see the default React app welcome screen. Now we are ready to start building our code highlighting app.

Understanding the Core Concepts

Before we start coding, let’s understand the core concepts involved:

  • React Components: We’ll build our app using React components. Components are reusable building blocks of a React application.
  • State: We’ll use state to store the code entered by the user. When the code changes, React will re-render the component to reflect the changes.
  • JSX: JSX is a syntax extension to JavaScript that allows us to write HTML-like code within our JavaScript files.
  • Regular Expressions (Regex): We’ll use regular expressions to match and identify different parts of the code (keywords, strings, comments, etc.).
  • CSS Styling: We will use CSS to apply different colors and styles to the highlighted code elements.

Building the Code Highlighter App: Step-by-Step

Now, let’s build the app step-by-step. We will start by creating the basic structure and then add the highlighting functionality.

1. Component Structure

Our app will consist of the following main components:

  • App.js: The main component that renders the entire application.
  • CodeEditor.js: A component that contains a textarea where the user will enter the code.
  • CodeViewer.js: A component that displays the highlighted code.

2. CodeEditor Component

Let’s create the `CodeEditor.js` component. Create a new file named `CodeEditor.js` in the `src` directory and add the following code:

import React from 'react';

function CodeEditor(props) {
  return (
    <div className="code-editor-container">
      <textarea
        className="code-editor"
        value={props.code}
        onChange={props.onChange}
        placeholder="Enter your code here..."
      />
    </div>
  );
}

export default CodeEditor;

Explanation:

  • We import `React` from ‘react’.
  • We define a functional component called `CodeEditor` that takes `props` as an argument.
  • Inside the component, we return a `div` element with the class name `code-editor-container`.
  • We include a `textarea` element for the user to enter the code.
  • `value={props.code}`: This binds the value of the textarea to the `code` prop passed from the parent component.
  • `onChange={props.onChange}`: This handles the changes in the textarea and calls the `onChange` function passed from the parent component.
  • `placeholder=”Enter your code here…”`: Provides a hint to the user.

Now, add some basic styling to `CodeEditor.css` in the `src` directory:

.code-editor-container {
  width: 100%;
  margin-bottom: 15px;
}

.code-editor {
  width: 100%;
  height: 200px;
  padding: 10px;
  font-family: monospace;
  font-size: 14px;
  border: 1px solid #ccc;
  border-radius: 4px;
  resize: vertical;
}

3. CodeViewer Component

Create a `CodeViewer.js` file in the `src` directory and add the following code:

import React from 'react';

function CodeViewer(props) {
  return (
    <div className="code-viewer-container">
      <pre className="code-viewer">
        {props.highlightedCode}
      </pre>
    </div>
  );
}

export default CodeViewer;

Explanation:

  • We import `React` from ‘react’.
  • We define a functional component called `CodeViewer` that takes `props` as an argument.
  • Inside the component, we return a `div` element with the class name `code-viewer-container`.
  • We use a `
    ` tag to preserve whitespace and line breaks in the code.
  • `{props.highlightedCode}`: This displays the highlighted code passed from the parent component.

Add some styling to `CodeViewer.css` in the `src` directory:

.code-viewer-container {
  width: 100%;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 10px;
  background-color: #f9f9f9;
  overflow-x: auto; /* For horizontal scrolling if the code is too wide */
}

.code-viewer {
  font-family: monospace;
  font-size: 14px;
  line-height: 1.4;
  white-space: pre-wrap; /* Preserve spaces and line breaks */
  word-break: break-all; /* Break long words to prevent overflow */
}

4. App.js Component (Main Component)

Now, let's modify the `App.js` file to integrate these components and manage the state. Replace the content of `App.js` in the `src` directory with the following code:

import React, { useState, useEffect } from 'react';
import CodeEditor from './CodeEditor';
import CodeViewer from './CodeViewer';
import './App.css'; // Import the App.css file

function App() {
  const [code, setCode] = useState('');
  const [highlightedCode, setHighlightedCode] = useState('');

  useEffect(() => {
    // Function to highlight the code
    const highlight = () => {
      // Regular expressions for highlighting (basic example)
      const keywordRegex = /b(function|if|else|for|while|return)b/g;
      const stringRegex = /"([^"\]*(\.[^"\]*)*)"/g;
      const commentRegex = /(//.*|/*[sS]*?*/)/g;

      let highlighted = code;

      // Highlight comments
      highlighted = highlighted.replace(commentRegex, '<span class="comment">$1</span>');

      // Highlight strings
      highlighted = highlighted.replace(stringRegex, '<span class="string">"$1"</span>');

      // Highlight keywords
      highlighted = highlighted.replace(keywordRegex, '<span class="keyword">$1</span>');

      setHighlightedCode(highlighted);
    };

    highlight(); // Initial highlight on component mount
  }, [code]); // Re-run effect when 'code' changes

  const handleCodeChange = (event) => {
    setCode(event.target.value);
  };

  return (
    <div className="app-container">
      <h2>Code Highlighter</h2>
      <CodeEditor code={code} onChange={handleCodeChange} />
      <CodeViewer highlightedCode={highlightedCode} />
    </div>
  );
}

export default App;

Explanation:

  • We import `useState` and `useEffect` from 'react'.
  • We import `CodeEditor` and `CodeViewer` components.
  • We define two state variables using `useState`:
    • `code`: Stores the code entered by the user.
    • `highlightedCode`: Stores the highlighted code.
  • `useEffect` Hook:
    • This hook is used to run the highlighting logic whenever the `code` state changes.
    • `highlight()` function: This function contains the core highlighting logic.
      • It defines regular expressions (`keywordRegex`, `stringRegex`, `commentRegex`) to match different code elements. These are basic examples and can be expanded.
      • It uses the `.replace()` method with the regular expressions to replace matched code elements with HTML `<span>` elements, adding CSS classes for styling.
      • `setHighlightedCode(highlighted)`: Updates the `highlightedCode` state with the highlighted code.
    • The dependency array `[code]` ensures that the effect runs whenever the `code` state changes.
    • The `highlight()` function is called initially when the component mounts.
  • `handleCodeChange` function: Updates the `code` state when the user types in the `CodeEditor`.
  • The `App` component returns the following JSX:
    • A heading `<h2>` for the app title.
    • `CodeEditor` component: Passes the `code` state and `handleCodeChange` function as props.
    • `CodeViewer` component: Passes the `highlightedCode` state as a prop.

Create `App.css` in the `src` directory and add the following CSS:

.app-container {
  max-width: 800px;
  margin: 20px auto;
  padding: 20px;
  border: 1px solid #ccc;
  border-radius: 8px;
}

.keyword {
  color: #007bff; /* Blue */
  font-weight: bold;
}

.string {
  color: #28a745; /* Green */
}

.comment {
  color: #6c757d; /* Gray */
  font-style: italic;
}

This CSS defines the styling for the app container and the different code elements (keywords, strings, and comments). You can customize these colors and styles to your liking.

5. Import CSS Files into index.js

To make sure the CSS is applied to your components, import the `App.css`, `CodeEditor.css`, and `CodeViewer.css` files into `index.js`:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

6. Running the App

Save all the files and run your React app using `npm start` in the terminal. You should see the following:

  • A text area where you can enter your code.
  • Below the text area, a section that displays the highlighted code in real-time.

Try pasting some code into the text area. You should see keywords, strings, and comments highlighted with different colors. If you don't see the highlighting, double-check your code for any typos or errors, especially in the regular expressions and CSS classes.

Common Mistakes and How to Fix Them

Here are some common mistakes and how to fix them:

  • Incorrect Regular Expressions: Regular expressions can be tricky. Make sure your regular expressions accurately match the code elements you want to highlight. Test your regex using online tools like regex101.com.
  • CSS Class Mismatches: Ensure your CSS class names match the class names used in your `highlight()` function. For example, if you use the class name `keyword` in your `highlight()` function, make sure you have a corresponding `.keyword` style in your CSS.
  • Incorrect Component Imports: Double-check that you've imported your components correctly in `App.js`.
  • State Not Updating: Make sure your state variables are being updated correctly using the `set...` functions (e.g., `setCode`, `setHighlightedCode`).
  • Missing Dependencies in `useEffect` : Make sure you have included all the necessary dependencies in the dependency array of the `useEffect` hook. In our case, the `code` dependency is crucial.
  • HTML Injection Vulnerability: While this tutorial provides a basic highlighting implementation, be aware that directly injecting HTML from user input can introduce security vulnerabilities (e.g., cross-site scripting (XSS)). For production environments, consider using a library like `dompurify` to sanitize the HTML before rendering it.

Expanding the Functionality

Here are some ideas to expand the functionality of your code highlighting app:

  • Support for More Languages: Add support for more programming languages by creating regular expressions for their syntax.
  • Line Numbers: Add line numbers to the `CodeViewer` component to make it easier to reference specific lines of code.
  • Theme Selection: Allow users to select different themes (e.g., light, dark, solarized) for the code highlighting.
  • Code Folding: Implement code folding to allow users to collapse and expand sections of code.
  • Error Highlighting: Integrate a code linter to highlight syntax errors.
  • Customization Options: Allow users to customize the colors and styles of the highlighting.
  • Copy to Clipboard: Add a button to copy the highlighted code to the clipboard.
  • Web Workers: For very large code snippets, consider using Web Workers to perform the highlighting in the background, preventing the UI from freezing.

Key Takeaways

  • You've learned how to create a basic code highlighting app using React.
  • You've understood the use of React components, state, JSX, and regular expressions.
  • You've learned how to use the `useEffect` hook to handle side effects like code highlighting.
  • You've gained practical experience with front-end development.

FAQ

Here are some frequently asked questions:

  1. How do I add support for a new programming language?

    You'll need to create regular expressions that match the syntax of the new language. Then, add the highlighting logic for the new language inside the `highlight()` function, and create CSS classes to style the new elements.

  2. How can I improve the performance of the highlighting?

    For large code snippets, consider using a library like `prismjs` or `highlight.js`, which are optimized for code highlighting. You can also use Web Workers to perform the highlighting in the background.

  3. How do I handle user input securely?

    Be careful when directly inserting user input into your HTML. Always sanitize user input before rendering it to prevent cross-site scripting (XSS) attacks. Use a library like `dompurify` to sanitize the HTML.

  4. Can I use this app for production?

    This is a basic implementation suitable for learning and small projects. For production, consider using a more robust code highlighting library and implementing security best practices.

  5. Where can I learn more about React and regular expressions?

    Check out the official React documentation at https://react.dev/ and resources like MDN Web Docs for regular expressions.

You've now built a functional and useful React application! This code highlighting app is a great starting point, and you can now customize it to meet your specific needs. Remember to experiment, practice, and explore the possibilities. As you continue to build and refine this app, you'll deepen your understanding of React and front-end development. The ability to quickly understand and share code is a valuable skill in the development world, and with this project, you've taken a significant step toward mastering it. Keep coding and keep learning!