<CodeBlock> Component

A formatted code block for displaying lovely lines of code.

Share
Code Editor

Where it's used

0.x.x
Loading 0.x.x releases...
1.x.x
Loading 1.x.x releases...
2.x.x
Loading 2.x.x releases...
3.x.x
Loading 3.x.x releases...
4.x.x
Loading 4.x.x releases...

Props

NameDescription
className
string
A className string which will be added to the outer element of this component.
code*
string
A string of highlighted HTML or React elements. These elements will be rendered into a <pre><code> container.

A plain string can be passed, but it will not be highlighted.
language
string
Used to set a global "language-*" className on both the pre and code element, for compatibility with language-specific highlight styles. This value should be identical to the language used to generate the highlighted code.
theme
string
Sets the color theme for the code block. Intended to match light and dark system appearance, for example through CSS @media (prefers-color-scheme).
Options: "light", "dark"
hasBarAbove
boolean
Intended for automatic use in CodeTabs, not meant as a consumer-facing prop. Set to true to remove border rounding from the top of the CodeBlock.
options
object
Additional options that enable supplementary code-block features.
Object contains nested props, see below:
options.showChrome
boolean
Set to true to display a window chrome bar UI above the code block.
options.highlight
string
Specify line numbers to highlight. Supports a comma-separate list of numbers and number ranges, where number ranges are dash-separated pairs of numbers.

For example: "5" highlights line 5; "2,5" highlights lines 2 and 5; "2-5" highlights lines 2, 3, 4, and 5; "2,6-8,11" highlights line 2, 6, 7, 8 and 11.
options.lineNumbers
boolean
Set to true to display line numbers on the left edge of the code block.
options.showClipboard
boolean
Set to true to show the copy-to-clipboard prompt and functionality.

Using features in MDX via CodeBlockConfig

To support richer configuration of code blocks in MDX, we've created a CodeBlockConfig component, which is available in Learn and Docs MDX contexts.

CodeBlockConfig is a wrapper component, similar to the ImageConfig component in our learn repo. CodeBlockConfig can be used to wrap and configure an individual fenced code block. It supports all of the properties of CodeBlock's options props, as detailed in the props table earlier on this page, with a few notable exceptions:

  • showClipboard is not supported, as the Copy button is shown by default in MDX contexts. Instead, a hideClipboard option is supported.
  • showChrome is not supported, as we currently would like to limit such ornamentation to JSX contexts, such as feature callouts on marketing pages.

Features & guidelines

Overflow

Longer lines of code may take up more space than the available content width. In these cases, code blocks will allow horizontal scrolling to view overflowing code.

Source

```
A line that goes on for a very long time so that it overflows the container in which it is located, which might be a pretty wide container.
```
```A line that goes on for a very long time so that it overflows the container in which it is located, which might be a pretty wide container.```

Result

A line that goes on for a very long time so that it overflows the container in which it is located, which might be a pretty wide container.
A line that goes on for a very long time so that it overflows the container in which it is located, which might be a pretty wide container.

Syntax Highlighting

Automatic syntax highlighting is supported in MDX contexts such as Learn and Docs. Syntax highlighting is set through the code fence's infostring, which is the string directly after the opening code fence. You can view a full list of supported syntax slugs and aliases in the refractor README.

Source

```javascript
const foo = 'bar'
function hello() {
  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'
}
```
```javascriptconst foo = 'bar'function hello() {  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'}```

Result

const foo = 'bar'
function hello() {
  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'
}
const foo = 'bar'function hello() {  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'}

Copy to Clipboard

The copy to clipboard button is useful to our practioners when they need to copy and paste content. In most use-cases the copy to clipboard button is necessary, so this feature is enabled by default on all Learn and Docs pages.

Source

```javascript
// Copy this code!
console.log("Hello world");
```
```javascript// Copy this code!console.log("Hello world");```

Result

// Copy this code!
console.log('Hello world')
// Copy this code!console.log('Hello world')

In some cases, such as when showing diffs, we might want to hide the copy-to-clipboard functionality. In MDX use cases, use the <CodeBlockConfig /> wrapper component with the hideClipboard prop, as shown below.

Source

<CodeBlockConfig hideClipboard>

```javascript
// Doing stuff you shouldn't copy
function sayHello() {
  console.log("Hello again");
}
```

</CodeBlockConfig>
<CodeBlockConfig hideClipboard> ```javascript// Doing stuff you shouldn't copyfunction sayHello() {  console.log("Hello again");}``` </CodeBlockConfig>

Result

// Doing stuff you shouldn't copy
function sayHello() {
  console.log('Hello again')
}
// Doing stuff you shouldn't copyfunction sayHello() {  console.log('Hello again')}
Shell snippet interpretation

Our copy-to-clipboard functionality automatically tries to detect shell snippets, and ensure only commands are copied, rather than all characters rendered in a shell session.

However, there are limitations to what is possible with this feature. To start, detection is fairly primitive - any code starting with a $ character on the first line will be interpreted as a shell snippet when copied. This is intended to allow the display of control characters such as $ and shell output in the code block, while ensuring that when copying the snippet, only the executable part of the snippet is copied to the clipboard.

As a basic example, the following snippet's Copy button should yield echo "hello world" rather than the full contents of the code block:

Source

```shell-session
$ echo "hello world"
hello world
```
```shell-session$ echo "hello world"hello world```

Result

$ echo "hello world"
hello world
$ echo "hello world"hello world

Further examples:

ScenarioSupportedWhat gets copiedExample
Single line commandsThe command will be copied without the leading $.🔗
Multi-line commandsThe multi-line command will be copied, without the leading $.🔗
Commands with outputThe command will be copied without the leading $ or the output.🔗
Non-shell SnippetsThe entire snippet will be copied.🔗
Multi-line with multiple commandsNot supported. Only the first command will be copied.🛑

Line Numbering

Use line numbers for long code blocks, or when you are calling out specific lines via line highlight.

Source

<CodeBlockConfig lineNumbers>

```javascript
const foo = 'bar'
function hello() {
  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'
}
```

</CodeBlockConfig>
<CodeBlockConfig lineNumbers> ```javascriptconst foo = 'bar'function hello() {  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'}``` </CodeBlockConfig>

Result

const foo = 'bar'
function hello() {
  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'
}
1234const foo = 'bar'function hello() {  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'}

Line Highlighting

Use line highlights to visually call out specific lines. The lineNumbers option should typically be used as well. Note that non-highlighted lines will be dimmed, and will not have syntax highlighting colors applied.

Source

<CodeBlockConfig lineNumbers highlight="3,5">

```javascript
console.log('Hello world!')
console.log('This is a second line.')
// Doing more stuff
function logAThirdLine() {
  console.log('Hello again')
}
```

</CodeBlockConfig>
<CodeBlockConfig lineNumbers highlight="3,5"> ```javascriptconsole.log('Hello world!')console.log('This is a second line.')// Doing more stufffunction logAThirdLine() {  console.log('Hello again')}``` </CodeBlockConfig>

Result

console.log('Hello world!')
console.log('This is a second line.')
// Doing more stuff
function logAThirdLine() {
  console.log('Hello again')
}
123456console.log('Hello world!')console.log('This is a second line.')// Doing more stufffunction logAThirdLine() {  console.log('Hello again')}

Heading

Code block headings should use a few actionable words and phrases to ensure efficient scanning and identification. Headings can start to stack and become hard to read at smaller viewports if they are too many characters. Aim for headings with 50 or fewer characters.

Source

<CodeBlockConfig heading="Say hello in English or French">

```javascript
const foo = 'bar'
function hello() {
  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'
}
```

</CodeBlockConfig>
<CodeBlockConfig heading="Say hello in English or French"> ```javascriptconst foo = 'bar'function hello() {  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'}``` </CodeBlockConfig>

Result

const foo = 'bar'
function hello() {
  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'
}
Say hello in English or French
const foo = 'bar'function hello() {  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'}

Filename

Add a filename to be shown above the snippet. Filenames should always correspond with an actual curated file that our users will be using or referencing to avoid confusion.

Source

<CodeBlockConfig filename="hello-world.js">

```javascript
const foo = 'bar'
function hello() {
  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'
}
```

</CodeBlockConfig>
<CodeBlockConfig filename="hello-world.js"> ```javascriptconst foo = 'bar'function hello() {  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'}``` </CodeBlockConfig>

Result

const foo = 'bar'
function hello() {
  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'
}
hello-world.js
const foo = 'bar'function hello() {  return Math.random() > 0.5 ? 'Hello' : 'Bonjour'}

Multi-language CodeTabs

The CodeTabs component, which is available in Learn and Docs MDX contexts, allows authors to create multi-snippet tabbed code blocks. <CodeTabs> is a wrapper component around child code blocks. Each child must be either a fenced code block, or must be a <CodeBlockConfig> which wraps a fenced code block.

When to use CodeTabs

Tabs should only be used when switching between similar content types such as:

  • Windows / macOS / Linux
  • HCL / JSON
  • JavaScript / BASH

Essentially either similar languages or OSs, or more broadly, equivalent approaches to a particular task or workflow.

Where space is limited, tabs will automatically collapse into a dropdown menu on the right side.

With fenced code child tabs

CodeTabs can be used directly with fenced code children.

Source

<CodeTabs>

```javascript
console.log("hello world")
```

```shell
echo "hello world"
```

</CodeTabs>
<CodeTabs> ```javascriptconsole.log("hello world")``` ```shellecho "hello world"``` </CodeTabs>

Result

JavaScript
console.log('hello world')
console.log('hello world')
echo "hello world"
echo "hello world"

With CodeBlockConfig child tabs

CodeTabs can be used with fenced code children wrapped with CodeBlockConfig configuration. Note as well that tabs can be mixed - some tabs can be plain fenced code and others can use CodeBlockConfig.

Source

<CodeTabs heading="Set your primary datacenter">

<CodeBlockConfig filename="consul-acl.hcl" lineNumbers highlight="3,6-8">

```hcl
primary_datacenter = "dc1"
acl {
  enabled        = true
  default_policy = "deny"
  down_policy    = "extend-cache"
  tokens {
    "agent" = "da666809-98ca-0e94-a99c-893c4bf5f9eb"
  }
}
```

</CodeBlockConfig>

<CodeBlockConfig filename="consul-acl.json" lineNumbers highlight="4,7-9">

```json
{
  "primary_datacenter": "dc1",
  "acl": {
    "enabled": true,
    "default_policy": "deny",
    "down_policy": "extend-cache",
    "tokens": {
      "agent": "da666809-98ca-0e94-a99c-893c4bf5f9eb"
    }
  }
}
```

</CodeBlockConfig>

</CodeTabs>
<CodeTabs heading="Set your primary datacenter"> <CodeBlockConfig filename="consul-acl.hcl" lineNumbers highlight="3,6-8"> ```hclprimary_datacenter = "dc1"acl {  enabled        = true  default_policy = "deny"  down_policy    = "extend-cache"  tokens {    "agent" = "da666809-98ca-0e94-a99c-893c4bf5f9eb"  }}``` </CodeBlockConfig> <CodeBlockConfig filename="consul-acl.json" lineNumbers highlight="4,7-9"> ```json{  "primary_datacenter": "dc1",  "acl": {    "enabled": true,    "default_policy": "deny",    "down_policy": "extend-cache",    "tokens": {      "agent": "da666809-98ca-0e94-a99c-893c4bf5f9eb"    }  }}``` </CodeBlockConfig> </CodeTabs>

Result

JSON
{
  "primary_datacenter": "dc1",
  "acl": {
    "enabled": true,
    "default_policy": "deny",
    "down_policy": "extend-cache",
    "tokens": {
      "agent": "da666809-98ca-0e94-a99c-893c4bf5f9eb"
    }
  }
}
consul-acl.hcl
1 2 3 4 5 6 7 8 9 1011{  "primary_datacenter": "dc1",  "acl": {    "enabled": true,    "default_policy": "deny",    "down_policy": "extend-cache",    "tokens": {      "agent": "da666809-98ca-0e94-a99c-893c4bf5f9eb"    }  }}
primary_datacenter = "dc1"
acl {
  enabled        = true
  default_policy = "deny"
  down_policy    = "extend-cache"
  tokens {
    "agent" = "da666809-98ca-0e94-a99c-893c4bf5f9eb"
  }
}
consul-acl.json
123456789primary_datacenter = "dc1"acl {  enabled        = true  default_policy = "deny"  down_policy    = "extend-cache"  tokens {    "agent" = "da666809-98ca-0e94-a99c-893c4bf5f9eb"  }}

With arbitary tab names

By default, CodeTabs will automatically set tab headings based on the language used for syntax highlighting in each child tab.

In some cases, we may want to set custom tab headings. This can be done by passing an array of heading strings to CodeTab's tabs prop.

Source

<CodeTabs tabs={[ "macOS", "Windows" ]}>

<CodeBlockConfig filename="hello-world.js">

```javascript
console.log('hello world')
```

</CodeBlockConfig>

```go
package main

import "fmt"

func main() {
  fmt.Println("hello world")
}
```

</CodeTabs>
<CodeTabs tabs={[ "macOS", "Windows" ]}> <CodeBlockConfig filename="hello-world.js"> ```javascriptconsole.log('hello world')``` </CodeBlockConfig> ```gopackage main import "fmt" func main() {  fmt.Println("hello world")}``` </CodeTabs>

Result

JavaScript
console.log('hello world')
hello-world.js
console.log('hello world')
package main

import "fmt"

func main() {
  fmt.Println("hello world")
}
package mainimport "fmt"func main() {  fmt.Println("hello world")}

JSX-only Features

The CodeBlock component supports a few extra features in JSX that are not used in MDX contexts. These features are detailed below.

Window chrome

The options.showChrome prop, which is only available in JSX contexts, allows consumers to display a bar of window-like UI chrome above the code block. This feature is most often used on feature overviews on marketing sites.

import "fmt"

func main() {
 fmt.Println("Hello world!")
}
import "fmt" func main() { fmt.Println("Hello world!")}

Theme

In JSX contexts, the consumer has the option to set the theme of the code block. Note however in the future, the theme prop may be ignored in favour of user preferences for light or dark colour schemes, for example via the @media (prefers-color-scheme) CSS media query.

"dark" theme

Set your primary datacenter
Go
package main

import "fmt"

func main() {
    ch := make(chan float64)
    ch <- 1.0e10    // magic number
    x, ok := <- ch
    defer fmt.Println("exiting now")
    go println(len("hello world!"))
    return
}
hello-world.go
1 2 3 4 5 6 7 8 9 101112package main import "fmt" func main() {    ch := make(chan float64)    ch <- 1.0e10    // magic number    x, ok := <- ch    defer fmt.Println("exiting now")    go println(len("hello world!"))    return}
primary_datacenter = "dc1"
acl {
  enabled        = true
  default_policy = "deny"
  down_policy    = "extend-cache"
  tokens {
    "agent" = "da666809-98ca-0e94-a99c-893c4bf5f9eb"
  }
}
consul-acl.hcl
123456789primary_datacenter = "dc1"acl {  enabled        = true  default_policy = "deny"  down_policy    = "extend-cache"  tokens {    "agent" = "da666809-98ca-0e94-a99c-893c4bf5f9eb"  }}

"light" theme

Set your primary datacenter
Go
package main

import "fmt"

func main() {
    ch := make(chan float64)
    ch <- 1.0e10    // magic number
    x, ok := <- ch
    defer fmt.Println("exiting now")
    go println(len("hello world!"))
    return
}
hello-world.go
1 2 3 4 5 6 7 8 9 101112package main import "fmt" func main() {    ch := make(chan float64)    ch <- 1.0e10    // magic number    x, ok := <- ch    defer fmt.Println("exiting now")    go println(len("hello world!"))    return}
primary_datacenter = "dc1"
acl {
  enabled        = true
  default_policy = "deny"
  down_policy    = "extend-cache"
  tokens {
    "agent" = "da666809-98ca-0e94-a99c-893c4bf5f9eb"
  }
}
consul-acl.hcl
123456789primary_datacenter = "dc1"acl {  enabled        = true  default_policy = "deny"  down_policy    = "extend-cache"  tokens {    "agent" = "da666809-98ca-0e94-a99c-893c4bf5f9eb"  }}

Code passed as JSX or HTML

When rendering highlighted code tokens, the CodeBlock component's code prop can accept either HTML or JSX that represents those tokens. This allows the component to function both in MDX contexts (where JSX tokens are passed) and in JSX contexts (where consumers will likely pass highlighted HTML).

With html code

package main

import "fmt"

func main() {
    ch := make(chan float64)
    ch <- 1.0e10    // magic number
    x, ok := <- ch
    defer fmt.Println("exiting now")
    go println(len("hello world!"))
    return
}
package main import "fmt" func main() {    ch := make(chan float64)    ch <- 1.0e10    // magic number    x, ok := <- ch    defer fmt.Println("exiting now")    go println(len("hello world!"))    return}

With jsx code

package main

import "fmt"

func main() {
    ch := make(chan float64)
    ch <- 1.0e10    // magic number
    x, ok := <- ch
    defer fmt.Println("exiting now")
    go println(len("hello world!"))
    return
}
package main

import "fmt"

func main() {
    ch := make(chan float64)
    ch <- 1.0e10    // magic number
    x, ok := <- ch
    defer fmt.Println("exiting now")
    go println(len("hello world!"))
    return
}