Imagine writing or reading more than a thousand lines of code in black and white text. This will be difficult and time-consuming since function names, comments, keywords, and even errors will be visually the same.
To resolve this, graphical changes are made, giving unique colors and styles to make certain parts of the code stand out, known as syntax highlighting. You can find syntax highlighting used in articles, documentation, and code editors.
In this tutorial, we will learn about syntax highlighter and its benefits, and how to build it with React.
Prerequisites
To follow along with this tutorial, you should be familiar with React and have Node installed in your system.
What Is Syntax Highlighting?
Syntax highlighting is a feature where text, especially source codes, is given unique design characteristics, such as a change in color or font, making it easier for developers to recognize aspects of their code such as keywords, identities, comments, etc.
The Benefits of Syntax Highlighting
Here are the benefits of syntax highlighting:
- It makes code more readable and easier to understand especially for a large code base. Developers/Readers can easily ignore large sections of comments or identity functions, classes, identifiers, etc depending on what they are looking for.
- In code editors, it helps programmers easily spot errors in their code like misspelled keywords, string literals with missing delimiters, etc since they would be highlighted within a color that indicates they are errors.
Building a Code Syntax Highlighter
Using react-syntax-highlighter we will be building a syntax highlighter where we can select a language to highlight our code in and a theme to be used for the highlighted code. We will also be using react-copy-to-clipboard to add functionality for copying code blocks.
Here is what we will be building in this tutorial:
Setting Up Our React App
Let’s create a new React app, install the needed dependencies and start up our development server using the following commands:
npx create-react-app syntax-highlighter
cd syntax-highlighter
npm i react-syntax-highlighter react-copy-to-clipboard
npm start
After completing the above let’s clean up our app a little bit. In the src directory, remove the following files:
- App.test.js
- logo.svg
- setupTests.js
- reportWebVitals.js
Next, in the index.js file, remove the import statement and the function call of reportWebVitals, then modify App.js to look like the following:
// src/App.js
import './App.css';
function App() {
return (
<div className='App'>
</div>
);
}
export default App;
Creating the UI
Head over to src/App.js file and first add the following import:
import { useState } from 'react';
Next, modify the App component to look like the following:
function App() {
const [text, setText] = useState('');
return (
<div className='highlighter'>
<div className='highlighter__code'>
<select name='languages'>
</select>
<textarea
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Write some code"
/>
</div>
<div className='highlighter__code'>
<select name='themes' >
</select>
<div className='highlighter__result'>
{/* highlighted syntax */}
</div>
</div>
</div>
);
}
Above, we have added the selects controls for selecting the language and theme to be used by the syntax highlighter. Although right now there is no options present, we will include them later. We have also added a textarea input where the code to be highlighted will be written.
Now, let’s include the styling we will be using for this tutorial. Replace everything in the App.css file with the following:
.highlighter{
display: flex;
gap: 20px;
align-items: center;
justify-content: center;
width: 90%;
margin: 0 auto;
height: 100vh;
flex-wrap: wrap;
}
.highlighter__code {
flex-basis: calc(50% - 40px);
}
.highlighter__result{
position: relative;
width: 100%;
min-height: 300px;
}
.highlighter__result > button{
position: absolute;
right: 0;
margin: 10px ;
}
textarea {
background-color: rgb(227, 229, 231);
border: none;
display: block;
}
textarea, pre{
min-height: 300px;
box-sizing: border-box;
padding: 10px;
width: 100%;
margin: 10px 0;
}
select {
width: 250px;
height: 30px;
border: 1px solid rgb(196 198 199);
}
textarea:focus {
outline: none;
}
Now when we open our app in the browser we will see the following:
Creating Syntax Highlighter
For creating the syntax highlighter, we will be using the SyntaxHighlighter component provided by react-syntax-highlighter. We just need to pass the code to be highlighted as a child of the component, then the language and theme as props.
In the src/App.js file, add the following imports:
import SyntaxHighlighter from "react-syntax-highlighter";
import * as themes from "react-syntax-highlighter/dist/esm/styles/hljs";
import supportedLanguages from 'react-syntax-highlighter/dist/cjs/languages/hljs/supported-languages';
Above, along with the SyntaxHighlighter component, we have also imported all the available themes and supported languages from the library.
Next, in the App component, add the following lines of code:
const defaultLanguage = 'javascript'
const defaultTheme = 'agate'
const [language, setLanguage] = useState(defaultLanguage);
const [theme, setTheme] = useState(defaultTheme)
Above we have created the state for the languages and themes select controls. We have also specified the defaults we want our syntax highlighter to have when it’s first rendered.
Next, let’s modify the select inputs to display the available languages and themes when they are clicked and also update their respective state when an option is selected.
Modify, the select input with the attribute name=’languages’ to the following:
<select
defaultValue={defaultLanguage}
name="languages"
onChange={(e) => setLanguage(e.target.value)}
>
{supportedLanguages.map((language, i) => (
<option key={i}>{language}</option>
))}
</select>
Next, modify, the select input with the attribute name=’themes’ to the following:
<select
defaultValue={defaultTheme}
name="themes"
onChange={(e) => setTheme(e.target.value)}
>
{Object.keys(themes).map((theme, i) => (
<option key={i}>{theme}</option>
))}
</select>
Now, add the following lines of code after the {/* highlighted syntax */} comment:
<SyntaxHighlighter language={language} style={themes[theme]}>
{text}
</SyntaxHighlighter>
With this, when we open our app in the browser and write in the textarea input, the highlights version will be displayed. We can also change the language and theme from the select input control.
Adding Functionality to Copying Code to the Clipboard
In most blogs and docs, you will see a feature where clicking an icon or text often located at the top left of the code block will copy that code to the clipboard. Let’s also include that in ours.
Using react-copy-to-clipboard, implementing this is really straightforward. We just need to pass the text to be copied to the text props of the provided CopyToClipboard component and a button or span element which can be clicked as a child of the component.
In the App component, add the following imports:
import CopyToClipboard from 'react-copy-to-clipboard';
Next, add the following lines of code before the SyntaxHighlighter component:
<CopyToClipboard text={text} onCopy={() => alert("Copied")}>
<button>Copy</button>
</CopyToClipboard>
Aside from the text and children props CopyToClipboard also receives an onCopy prop which receives a function to be called when the text has been copied. Above using this prop we are sending an alert when the text has been copied.
With this, since we have previously added our styling when we head over to our app in the browser we will see a copy button at the top-left of the highlighted code.
Conclusion
The use of syntax highlighter can’t be overlooked in coding seeing as how it changes the design characteristics of code which in turn improves developer productivity. In this tutorial, we have learned about syntax highlighter and how to create it. With this, you should be able to easily add it to your app.
The complete code for this tutorial is available on GitHub.