--- id: code-blocks description: Handling code blocks in Docusaurus Markdown slug: /markdown-features/code-blocks --- # Code blocks import BrowserWindow from '@site/src/components/BrowserWindow'; import CodeBlock from '@theme/CodeBlock'; Code blocks within documentation are super-powered 💪. ## Code title {#code-title} You can add a title to the code block by adding a `title` key after the language (leave a space between them). ````md ```jsx title="/src/components/HelloCodeTitle.js" function HelloCodeTitle(props) { return

Hello, {props.name}

; } ``` ```` ```mdx-code-block ``` ```jsx title="/src/components/HelloCodeTitle.js" function HelloCodeTitle(props) { return

Hello, {props.name}

; } ``` ```mdx-code-block
``` ## Syntax highlighting {#syntax-highlighting} Code blocks are text blocks wrapped around by strings of 3 backticks. You may check out [this reference](https://mdxjs.com/docs/) for the specifications of MDX. ````md ```js console.log('Every repo must come with a mascot.'); ``` ```` Use the matching language meta string for your code block, and Docusaurus will pick up syntax highlighting automatically, powered by [Prism React Renderer](https://github.com/FormidableLabs/prism-react-renderer). ```js console.log('Every repo must come with a mascot.'); ``` ### Theming {#theming} By default, the Prism [syntax highlighting theme](https://github.com/FormidableLabs/prism-react-renderer#theming) we use is [Palenight](https://github.com/FormidableLabs/prism-react-renderer/blob/master/packages/prism-react-renderer/src/themes/palenight.ts). You can change this to another theme by passing `theme` field in `prism` as `themeConfig` in your docusaurus.config.js. For example, if you prefer to use the `dracula` highlighting theme: ```js title="docusaurus.config.js" import {themes as prismThemes} from 'prism-react-renderer'; export default { themeConfig: { prism: { // highlight-next-line theme: prismThemes.dracula, }, }, }; ``` Because a Prism theme is just a JS object, you can also write your own theme if you are not satisfied with the default. Docusaurus enhances the `github` and `vsDark` themes to provide richer highlight, and you can check our implementations for the [light](https://github.com/facebook/docusaurus/blob/main/website/src/utils/prismLight.ts) and [dark](https://github.com/facebook/docusaurus/blob/main/website/src/utils/prismDark.ts) code block themes. ### Supported Languages {#supported-languages} By default, Docusaurus comes with a subset of [commonly used languages](https://github.com/FormidableLabs/prism-react-renderer/blob/master/packages/generate-prism-languages/index.ts#L9-L23). :::warning Some popular languages like Java, C#, or PHP are not enabled by default. ::: To add syntax highlighting for any of the other [Prism-supported languages](https://prismjs.com/#supported-languages), define it in an array of additional languages. :::note Each additional language has to be a valid Prism component name. For example, Prism would map the _language_ `cs` to `csharp`, but only `prism-csharp.js` exists as a _component_, so you need to use `additionalLanguages: ['csharp']`. You can look into `node_modules/prismjs/components` to find all components (languages) available. ::: For example, if you want to add highlighting for the PowerShell language: ```js title="docusaurus.config.js" export default { // ... themeConfig: { prism: { // highlight-next-line additionalLanguages: ['powershell'], }, // ... }, }; ``` After adding `additionalLanguages`, restart Docusaurus. If you want to add highlighting for languages not yet supported by Prism, you can swizzle `prism-include-languages`: ```bash npm2yarn npm run swizzle @docusaurus/theme-classic prism-include-languages ``` It will produce `prism-include-languages.js` in your `src/theme` folder. You can add highlighting support for custom languages by editing `prism-include-languages.js`: ```js title="src/theme/prism-include-languages.js" const prismIncludeLanguages = (Prism) => { // ... additionalLanguages.forEach((lang) => { require(`prismjs/components/prism-${lang}`); }); // highlight-next-line require('/path/to/your/prism-language-definition'); // ... }; ``` You can refer to [Prism's official language definitions](https://github.com/PrismJS/prism/tree/master/components) when you are writing your own language definitions. When adding a custom language definition, you do not need to add the language to the `additionalLanguages` config array, since Docusaurus only looks up the `additionalLanguages` strings in languages that Prism provides. Adding the language import in `prism-include-languages.js` is sufficient. ## Line highlighting {#line-highlighting} ### Highlighting with comments {#highlighting-with-comments} You can use comments with `highlight-next-line`, `highlight-start`, and `highlight-end` to select which lines are highlighted. ````md ```js function HighlightSomeText(highlight) { if (highlight) { // highlight-next-line return 'This text is highlighted!'; } return 'Nothing highlighted'; } function HighlightMoreText(highlight) { // highlight-start if (highlight) { return 'This range is highlighted!'; } // highlight-end return 'Nothing highlighted'; } ``` ```` ```mdx-code-block ``` ```js function HighlightSomeText(highlight) { if (highlight) { // highlight-next-line return 'This text is highlighted!'; } return 'Nothing highlighted'; } function HighlightMoreText(highlight) { // highlight-start if (highlight) { return 'This range is highlighted!'; } // highlight-end return 'Nothing highlighted'; } ``` ```mdx-code-block ``` Supported commenting syntax: | Style | Syntax | | ---------- | ------------------------ | | C-style | `/* ... */` and `// ...` | | JSX-style | `{/* ... */}` | | Bash-style | `# ...` | | HTML-style | `` | We will do our best to infer which set of comment styles to use based on the language, and default to allowing _all_ comment styles. If there's a comment style that is not currently supported, we are open to adding them! Pull requests welcome. Note that different comment styles have no semantic difference, only their content does. You can set your own background color for highlighted code line in your `src/css/custom.css` which will better fit to your selected syntax highlighting theme. The color given below works for the default highlighting theme (Palenight), so if you are using another theme, you will have to tweak the color accordingly. ```css title="/src/css/custom.css" :root { --docusaurus-highlighted-code-line-bg: rgb(72, 77, 91); } /* If you have a different syntax highlighting theme for dark mode. */ [data-theme='dark'] { /* Color which works with dark mode syntax highlighting theme */ --docusaurus-highlighted-code-line-bg: rgb(100, 100, 100); } ``` If you also need to style the highlighted code line in some other way, you can target on `theme-code-block-highlighted-line` CSS class. ### Highlighting with metadata string {#highlighting-with-metadata-string} You can also specify highlighted line ranges within the language meta string (leave a space after the language). To highlight multiple lines, separate the line numbers by commas or use the range syntax to select a chunk of lines. This feature uses the `parse-number-range` library and you can find [more syntax](https://www.npmjs.com/package/parse-numeric-range) on their project details. ````md ```jsx {1,4-6,11} import React from 'react'; function MyComponent(props) { if (props.isBar) { return
Bar
; } return
Foo
; } export default MyComponent; ``` ```` ```mdx-code-block ``` ```jsx {1,4-6,11} import React from 'react'; function MyComponent(props) { if (props.isBar) { return
Bar
; } return
Foo
; } export default MyComponent; ``` ```mdx-code-block
``` :::tip prefer comments Prefer highlighting with comments where you can. By inlining highlight in the code, you don't have to manually count the lines if your code block becomes long. If you add/remove lines, you also don't have to offset your line ranges. ````diff - ```jsx {3} + ```jsx {4} function HighlightSomeText(highlight) { if (highlight) { + console.log('Highlighted text found'); return 'This text is highlighted!'; } return 'Nothing highlighted'; } ``` ```` Below, we will introduce how the magic comment system can be extended to define custom directives and their functionalities. The magic comments would only be parsed if a highlight metastring is not present. ::: ### Custom magic comments {#custom-magic-comments} `// highlight-next-line` and `// highlight-start` etc. are called "magic comments", because they will be parsed and removed, and their purposes are to add metadata to the next line, or the section that the pair of start- and end-comments enclose. You can declare custom magic comments through theme config. For example, you can register another magic comment that adds a `code-block-error-line` class name: ```mdx-code-block ``` ```js export default { themeConfig: { prism: { magicComments: [ // Remember to extend the default highlight class name as well! { className: 'theme-code-block-highlighted-line', line: 'highlight-next-line', block: {start: 'highlight-start', end: 'highlight-end'}, }, // highlight-start { className: 'code-block-error-line', line: 'This will error', }, // highlight-end ], }, }, }; ``` ```mdx-code-block ``` ```css .code-block-error-line { background-color: #ff000020; display: block; margin: 0 calc(-1 * var(--ifm-pre-padding)); padding: 0 var(--ifm-pre-padding); border-left: 3px solid #ff000080; } ``` ```mdx-code-block ``` ````md In JavaScript, trying to access properties on `null` will error. ```js const name = null; // This will error console.log(name.toUpperCase()); // Uncaught TypeError: Cannot read properties of null (reading 'toUpperCase') ``` ```` ```mdx-code-block ``` ```mdx-code-block ``` In JavaScript, trying to access properties on `null` will error. ```js const name = null; // This will error console.log(name.toUpperCase()); // Uncaught TypeError: Cannot read properties of null (reading 'toUpperCase') ``` ```mdx-code-block ``` If you use number ranges in metastring (the `{1,3-4}` syntax), Docusaurus will apply the **first `magicComments` entry**'s class name. This, by default, is `theme-code-block-highlighted-line`, but if you change the `magicComments` config and use a different entry as the first one, the meaning of the metastring range will change as well. You can disable the default line highlighting comments with `magicComments: []`. If there's no magic comment config, but Docusaurus encounters a code block containing a metastring range, it will error because there will be no class name to apply—the highlighting class name, after all, is just a magic comment entry. Every magic comment entry will contain three keys: `className` (required), `line`, which applies to the directly next line, or `block` (containing `start` and `end`), which applies to the entire block enclosed by the two comments. Using CSS to target the class can already do a lot, but you can unlock the full potential of this feature through [swizzling](../../swizzling.mdx). ```bash npm2yarn npm run swizzle @docusaurus/theme-classic CodeBlock/Line ``` The `Line` component will receive the list of class names, based on which you can conditionally render different markup. ## Line numbering {#line-numbering} You can enable line numbering for your code block by using `showLineNumbers` key within the language meta string (don't forget to add space directly before the key). ````md ```jsx showLineNumbers import React from 'react'; export default function MyComponent(props) { return
Foo
; } ``` ```` ```mdx-code-block ``` ```jsx showLineNumbers import React from 'react'; export default function MyComponent(props) { return
Foo
; } ``` ```mdx-code-block
``` By default, the counter starts at line number 1. It's possible to pass a custom counter start value to split large code blocks for readability: ````md ```jsx showLineNumbers=3 export default function MyComponent(props) { return
Foo
; } ``` ```` ```mdx-code-block ``` ```jsx showLineNumbers=3 export default function MyComponent(props) { return
Foo
; } ``` ```mdx-code-block
``` ## Interactive code editor {#interactive-code-editor} (Powered by [React Live](https://github.com/FormidableLabs/react-live)) You can create an interactive coding editor with the `@docusaurus/theme-live-codeblock` plugin. First, add the plugin to your package. ```bash npm2yarn npm install --save @docusaurus/theme-live-codeblock ``` You will also need to add the plugin to your `docusaurus.config.js`. ```js {3} export default { // ... themes: ['@docusaurus/theme-live-codeblock'], // ... }; ``` To use the plugin, create a code block with `live` attached to the language meta string. ````md ```jsx live function Clock(props) { const [date, setDate] = useState(new Date()); useEffect(() => { const timerID = setInterval(() => tick(), 1000); return function cleanup() { clearInterval(timerID); }; }); function tick() { setDate(new Date()); } return (

It is {date.toLocaleTimeString()}.

); } ``` ```` The code block will be rendered as an interactive editor. Changes to the code will reflect on the result panel live. ```mdx-code-block ``` ```jsx live function Clock(props) { const [date, setDate] = useState(new Date()); useEffect(() => { const timerID = setInterval(() => tick(), 1000); return function cleanup() { clearInterval(timerID); }; }); function tick() { setDate(new Date()); } return (

It is {date.toLocaleTimeString()}.

); } ``` ```mdx-code-block
``` ### Imports {#imports} :::warning react-live and imports It is not possible to import components directly from the react-live code editor, you have to define available imports upfront. ::: By default, all React imports are available. If you need more imports available, swizzle the react-live scope: ```bash npm2yarn npm run swizzle @docusaurus/theme-live-codeblock ReactLiveScope -- --eject ``` ```jsx title="src/theme/ReactLiveScope/index.js" import React from 'react'; // highlight-start const ButtonExample = (props) => (