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.
1import { CodeBlock } from 'react-code-block';23function CodeBlockDemo() {4return (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.
1import { CodeBlock } from 'react-code-block';23function CodeBlockDemo({ code, language }) {4return (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}1415const code = `16async function sayHello(name) {17console.log('Hello', name);18}19`;2021<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.
1import { CodeBlock } from 'react-code-block';23function CodeBlockDemo({ code, language }) {4return (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}
1const welcomeMessage = "Hello,";2let target = "world!";34function greet(target) {5console.log(welcomeMessage + " " + target);6}78greet(target);910for (let i = 0; i < 5; i++) {11console.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.
1import { CodeBlock } from 'react-code-block';23function CodeBlockDemo({ code, language }) {4return (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<div9className={`table-row ${10isLineHighlighted ? 'bg-violet-500/30' : 'opacity-60'11}`}12>13<CodeBlock.LineNumber14className={`table-cell pl-6 pr-4 text-sm text-right select-none ${15isLineHighlighted ? '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}
1const welcomeMessage = "Hello,";2let target = "world!";34function greet(target) {5console.log(welcomeMessage + " " + target);6}78greet(target);910for (let i = 0; i < 5; i++) {11console.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.
1import { CodeBlock } from 'react-code-block';23function CodeBlockDemo({ code, language }) {4return (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<span11className={12isTokenHighlighted13? '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:
1import { CodeBlock } from 'react-code-block';2import { useCopyToClipboard } from 'react-use';34function CodeBlockDemo({ code, language }) {5const [state, copyToClipboard] = useCopyToClipboard();67const copyCode = () => {8// Logic to copy `code`9copyToClipboard(code);10};1112return (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>2324<button25className="bg-white rounded-full px-3.5 py-1.5 absolute top-2 right-2 text-sm font-semibold"26onClick={copyCode}27>28{state.value ? 'Copied!' : 'Copy code'}29</button>30</div>31</CodeBlock>32);33}3435export default CodeBlockDemo;
1const welcomeMessage = "Hello,";2let target = "world!";34function greet(target) {5console.log(welcomeMessage + " " + target);6}78greet(target);910for (let i = 0; i < 5; i++) {11console.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.
1import { CodeBlock } from 'react-code-block';23function CodeBlockDemo({ code, language, filename }) {4return (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>910<CodeBlock.Code className="!px-0">11{({ isLineHighlighted }) => (12<div13className={`table-row ${14isLineHighlighted ? 'bg-emerald-400/25' : ''15}`}16>17{/* Rendering a plus sign */}18<div19className={`table-cell px-4 text-emerald-400 select-none ${20isLineHighlighted ? '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>3233{/* 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}4142export default CodeBlockDemo;
+1const welcomeMessage = "Hello,";+2let target = "world!";+3+4function greet(target) {+5console.log(welcomeMessage + " " + target);+6}+7+8greet(target);+9+10for (let i = 0; i < 5; i++) {+11console.log(`Count: ${i}`);+12}
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.
1import { CodeBlock } from 'react-code-block';2import { themes } from 'prism-react-renderer';34function CodeBlockDemo({ code, language }) {5return (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}
1const welcomeMessage = "Hello,";2let target = "world!";34function greet(target) {5console.log(welcomeMessage + " " + target);6}78greet(target);910for (let i = 0; i < 5; i++) {11console.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)