Docs
Documentation
Syntax Highlighting

Syntax Highlighting

Nextra uses Shiki to do syntax highlighting at build time. It’s very reliable and performant. For example, adding this in your Markdown file:

Markdown
```js
console.log('hello, world')
```

Result in this:

console.log('hello, world')

Features

Inlined Code

Inlined syntax highlighting like let x = 1 is also supported via the {:} syntax:

Inlined syntax highlighting is also supported: let x = 1

Filenames and Titles

You can add a filename or a title to your code blocks by adding a filename attribute:

Renders:

example.js
console.log('hello, world')

Highlighting Lines

You can highlight specific lines of code by adding a {} attribute to the code block:

import { useState } from 'react'
 
function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}
 

You can highlight only a part of the occurrences of that substring by adding a number it: /str/1, or multiple: /str/1-3, /str/1,3.

Line Numbers

You can add line numbers to your code blocks by adding a showLineNumbers attribute:

import { useState } from 'react'
 
function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(count + 1)}>{count}</button>
}
 

Supported Languages

Check this list for all supported languages.

Customize the Theme

Nextra uses CSS variables to define the colors for tokens. You can inject a global CSS to customize them under light/dark themes. For example this is the default tokens and you can override any of these:

styles.css
:root {
  --shiki-color-text: #414141;
  --shiki-color-background: transparent;
  --shiki-token-constant: #1976d2;
  --shiki-token-string: #22863a;
  --shiki-token-comment: #aaa;
  --shiki-token-keyword: #d32f2f;
  --shiki-token-parameter: #ff9800;
  --shiki-token-function: #6f42c1;
  --shiki-token-string-expression: #22863a;
  --shiki-token-punctuation: #212121;
  --shiki-token-link: #22863a;
}
 
.dark {
  --shiki-color-text: #d1d1d1;
  --shiki-token-constant: #79b8ff;
  --shiki-token-string: #ffab70;
  --shiki-token-comment: #6b737c;
  --shiki-token-keyword: #f97583;
  --shiki-token-parameter: #ff9800;
  --shiki-token-function: #b392f0;
  --shiki-token-string-expression: #4bb74a;
  --shiki-token-punctuation: #bbb;
  --shiki-token-link: #ffab70;
}

With Dynamic Content

Since syntax highlighting is done at build time, you can’t use dynamic content in your code blocks. However, since MDX is very powerful there is a workaround via client JS. For example:

dynamic_code.js
function hello () {
  const x = 2 + 3
  console.log(1)
}
Increase the numberChange to `1 + 1`

This workaround has a limitation that updated content won’t be re-highlighted. For example if we update the number to 1 + 1, it will be incorrectly highlighted.

Disable Syntax Highlighting

You can opt out of syntax highlighting for using one of your own. You can disable syntax highlighting globally by setting codeHighlight: false in your Nextra configuration (next.config.js file).

KeyTypeDescriptionExample
codeHighlightbooleanEnable or disable syntax highlighting.codeHighlight: true

Custom Grammar

Shiki accepts a VSCode TextMate Grammar for syntax highlighting with custom language grammars.

You can provide these grammars by overriding the getHighlighter function in mdxOptions.rehypePrettyCodeOptions option in your Nextra config inside next.config.js:

next.config.js
import { BUNDLED_LANGUAGES } from 'shiki'
 
nextra({
  // ... other options
  mdxOptions: {
    rehypePrettyCodeOptions: {
      getHighlighter: (options) =>
        getHighlighter({
          ...options,
          langs: [
            ...BUNDLED_LANGUAGES,
            // custom grammar options, see the Shiki documentation for how to provide these options
            {
              id: 'my-lang',
              scopeName: 'source.my-lang',
              aliases: ['mylang'], // Along with id, aliases will be included in the allowed names you can use when writing markdown.
              path: '@/public/syntax/grammar.tmLanguage.json',
            },
          ],
        }),
    },
  },
})

Custom Themes

Within mdxOptions.rehypePrettyCodeOptions you may also provide custom themes instead of relying on CSS Variables:

next.config.js
nextra({
  // ... other options
  mdxOptions: {
    rehypePrettyCodeOptions: {
      // VSCode theme or built-in Shiki theme, see Shiki documentation for more information
      theme: JSON.parse(
        readFileSync('./public/syntax/arctis_light.json', 'utf8')
      )
    }
  }
})