Usage

Usage

Installation

Start by installing react-code-block and its peer-dependency prism-react-renderer.

npm i react-code-block prism-react-renderer

If you prefer using Shiki as the syntax highlighter instead, follow this guide to get started and come back here for all the customization options.

Basic example

React Code Block exposes all the un-styled primitives you need to build a code block component through its CodeBlock component and various other subcomponents attached to it.

1
import { CodeBlock } from 'react-code-block';
2
3
function CodeBlockDemo() {
4
return (
5
<CodeBlock code="console.log('Hello World!')" language="js">
6
<CodeBlock.Code className="bg-black">
7
<CodeBlock.LineContent>
8
<CodeBlock.Token />
9
</CodeBlock.LineContent>
10
</CodeBlock.Code>
11
</CodeBlock>
12
);
13
}
console.log('Hello World!')

Doesn't look very exciting just yet. Because these components are un-styled, you have to add the styles to make your code block look the way you want it to be. With a little bit of CSS(using TailwindCSS in the examples), we can completely change the way the code block looks like.

1
import { CodeBlock } from 'react-code-block';
2
3
function CodeBlockDemo({ code, language }) {
4
return (
5
<CodeBlock code={code} language={language}>
6
<CodeBlock.Code className="bg-gray-900 p-6 rounded-xl shadow-lg">
7
<CodeBlock.LineContent>
8
<CodeBlock.Token />
9
</CodeBlock.LineContent>
10
</CodeBlock.Code>
11
</CodeBlock>
12
);
13
}
14
15
const code = `
16
async function sayHello(name) {
17
console.log('Hello', name);
18
}
19
`;
20
21
<CodeBlockDemo code={code} />;
async function sayHello(name) {
console.log('Hello', name);
}

Showing line numbers

To render line numbers for each line in the code block, you can use the CodeBlock.LineNumber component. A common approach is to render the line numbers on the left column. To keep line numbers and the code aligned correctly, you can use CSS Grids or Table layout.

1
import { CodeBlock } from 'react-code-block';
2
3
function CodeBlockDemo({ code, language }) {
4
return (
5
<CodeBlock code={code} language={language}>
6
<CodeBlock.Code className="bg-gray-900 p-6 rounded-xl shadow-lg">
7
<div className="table-row">
8
<CodeBlock.LineNumber className="table-cell pr-4 text-sm text-gray-500 text-right select-none" />
9
<CodeBlock.LineContent className="table-cell">
10
<CodeBlock.Token />
11
</CodeBlock.LineContent>
12
</div>
13
</CodeBlock.Code>
14
</CodeBlock>
15
);
16
}
1
const welcomeMessage = "Hello,";
2
let target = "world!";
3
4
function greet(target) {
5
console.log(welcomeMessage + " " + target);
6
}
7
8
greet(target);
9
10
for (let i = 0; i < 5; i++) {
11
console.log(`Count: ${i}`);
12
}

Line highlighting

You can highlight specific lines or line-ranges in your code via the lines prop on CodeBlock component. State information of which line should be highlighted is made available through isLineHighlighted render prop on CodeBlock.Code component, so you can add styles for how a line should be highlighted.

1
import { CodeBlock } from 'react-code-block';
2
3
function CodeBlockDemo({ code, language }) {
4
return (
5
<CodeBlock code={code} language={language} lines={['4:6', 8]}>
6
<CodeBlock.Code className="bg-gray-900 py-6 rounded-xl shadow-lg">
7
{({ isLineHighlighted }) => (
8
<div
9
className={`table-row ${
10
isLineHighlighted ? 'bg-violet-500/30' : 'opacity-60'
11
}`}
12
>
13
<CodeBlock.LineNumber
14
className={`table-cell pl-6 pr-4 text-sm text-right select-none ${
15
isLineHighlighted ? 'text-gray-300' : 'text-gray-500'
16
}`}
17
/>
18
<CodeBlock.LineContent className="table-cell w-full pr-6">
19
<CodeBlock.Token />
20
</CodeBlock.LineContent>
21
</div>
22
)}
23
</CodeBlock.Code>
24
</CodeBlock>
25
);
26
}
1
const welcomeMessage = "Hello,";
2
let target = "world!";
3
4
function greet(target) {
5
console.log(welcomeMessage + " " + target);
6
}
7
8
greet(target);
9
10
for (let i = 0; i < 5; i++) {
11
console.log(`Count: ${i}`);
12
}

Word highlighting

Specific words can be highlighted within a code block using words prop on the CodeBlock component. State information of which word to highlight is made available through isTokenHighlighted render prop on CodeBlock.Token component. This can be used to style the highlighted words accordingly.

1
import { CodeBlock } from 'react-code-block';
2
3
function CodeBlockDemo({ code, language }) {
4
return (
5
<CodeBlock code={code} language={language} words={['/greet/4:8', 'target']}}>
6
<CodeBlock.Code className="bg-gray-900 p-6 rounded-xl shadow-lg">
7
<CodeBlock.LineContent>
8
<CodeBlock.Token>
9
{({ isTokenHighlighted, children }) => (
10
<span
11
className={
12
isTokenHighlighted
13
? 'bg-violet-500/20 rounded-md px-1 py-0.5'
14
: ''
15
}
16
>
17
{children}
18
</span>
19
)}
20
</CodeBlock.Token>
21
</CodeBlock.LineContent>
22
</CodeBlock.Code>
23
</CodeBlock>
24
);
25
}
const welcomeMessage = "Hello,";
let target = "world!";
function greet(target) {
console.log(welcomeMessage + " " + target);
}
greet(target);
for (let i = 0; i < 5; i++) {
console.log(`Count: ${i}`);
}

Copy code to clipboard button

There is no built-in way to show a "Copy code" button in the code block. This is because both the styling and functionality depends on your project and the APIs / libraries you are using to copy data to user's clipboard. Therefore, you have to implement this feature on your own. An example of how it could look like:

1
import { CodeBlock } from 'react-code-block';
2
import { useCopyToClipboard } from 'react-use';
3
4
function CodeBlockDemo({ code, language }) {
5
const [state, copyToClipboard] = useCopyToClipboard();
6
7
const copyCode = () => {
8
// Logic to copy `code`
9
copyToClipboard(code);
10
};
11
12
return (
13
<CodeBlock code={code} language={language}>
14
<div className="relative">
15
<CodeBlock.Code className="bg-gray-900 !p-6 rounded-xl shadow-lg">
16
<div className="table-row">
17
<CodeBlock.LineNumber className="table-cell pr-4 text-sm text-gray-500 text-right select-none" />
18
<CodeBlock.LineContent className="table-cell">
19
<CodeBlock.Token />
20
</CodeBlock.LineContent>
21
</div>
22
</CodeBlock.Code>
23
24
<button
25
className="bg-white rounded-full px-3.5 py-1.5 absolute top-2 right-2 text-sm font-semibold"
26
onClick={copyCode}
27
>
28
{state.value ? 'Copied!' : 'Copy code'}
29
</button>
30
</div>
31
</CodeBlock>
32
);
33
}
34
35
export default CodeBlockDemo;
1
const welcomeMessage = "Hello,";
2
let target = "world!";
3
4
function greet(target) {
5
console.log(welcomeMessage + " " + target);
6
}
7
8
greet(target);
9
10
for (let i = 0; i < 5; i++) {
11
console.log(`Count: ${i}`);
12
}

Rendering additional elements

Since all the CodeBlock components are composable in nature, you have complete freedom to render additional elements in your code blocks. This could be showing the filename, language used, captions, etc.

1
import { CodeBlock } from 'react-code-block';
2
3
function CodeBlockDemo({ code, language, filename }) {
4
return (
5
<CodeBlock code={code} language={language} lines={['4:6']}>
6
<div className="relative bg-gray-900 rounded-xl overflow-hidden shadow-lg">
7
{/* Filename */}
8
<div className="text-sm text-gray-400 px-6 py-4">{filename}</div>
9
10
<CodeBlock.Code className="!px-0">
11
{({ isLineHighlighted }) => (
12
<div
13
className={`table-row ${
14
isLineHighlighted ? 'bg-emerald-400/25' : ''
15
}`}
16
>
17
{/* Rendering a plus sign */}
18
<div
19
className={`table-cell px-4 text-emerald-400 select-none ${
20
isLineHighlighted ? 'opacity-100' : 'opacity-0'
21
}`}
22
>
23
+
24
</div>
25
<CodeBlock.LineNumber className="table-cell pr-4 text-sm text-gray-500 text-right select-none" />
26
<CodeBlock.LineContent className="table-cell w-full pr-6">
27
<CodeBlock.Token />
28
</CodeBlock.LineContent>
29
</div>
30
)}
31
</CodeBlock.Code>
32
33
{/* Language being used */}
34
<div className="text-sm text-gray-400 px-6 pb-4 text-right uppercase select-none">
35
{language}
36
</div>
37
</div>
38
</CodeBlock>
39
);
40
}
41
42
export default CodeBlockDemo;
hello.js
+
1
const welcomeMessage = "Hello,";
+
2
let target = "world!";
+
3
+
4
function greet(target) {
+
5
console.log(welcomeMessage + " " + target);
+
6
}
+
7
+
8
greet(target);
+
9
+
10
for (let i = 0; i < 5; i++) {
+
11
console.log(`Count: ${i}`);
+
12
}
js

Theming

React Code Block uses prism-react-renderer under the hood for syntax highlighting. Default theme is vsDark and it can be changed using the theme prop in the CodeBlock component. Follow this guide (opens in a new tab) by prism-react-renderer for custom themes.

1
import { CodeBlock } from 'react-code-block';
2
import { themes } from 'prism-react-renderer';
3
4
function CodeBlockDemo({ code, language }) {
5
return (
6
<CodeBlock code={code} language={language} theme={themes.github}>
7
<CodeBlock.Code className="bg-white p-6 rounded-lg shadow">
8
<div className="table-row">
9
<CodeBlock.LineNumber className="table-cell pr-4 text-xs text-gray-400 text-right select-none" />
10
<CodeBlock.LineContent className="table-cell">
11
<CodeBlock.Token />
12
</CodeBlock.LineContent>
13
</div>
14
</CodeBlock.Code>
15
</CodeBlock>
16
);
17
}
1
const welcomeMessage = "Hello,";
2
let target = "world!";
3
4
function greet(target) {
5
console.log(welcomeMessage + " " + target);
6
}
7
8
greet(target);
9
10
for (let i = 0; i < 5; i++) {
11
console.log(`Count: ${i}`);
12
}

Support for more languages

Please follow the guide by prism-react-renderer for this – github.com/FormidableLabs/prism-react-renderer#custom-language-support (opens in a new tab)