close
  • English
  • Code blocks

    Rspress uses Shiki for syntax highlighting at compile time, which means better runtime performance.

    When using code blocks in multiple languages, the corresponding language is automatically detected at compile time, and the runtime bundle size does not increase. For supported programming languages, refer to the Shiki supported languages list.

    Basic usage

    You can use the ``` syntax to create code blocks. For example:

    ```js
    console.log('Hello World');
    ```

    It will be rendered as:

    console.log('Hello World');

    Code block title

    You can use the title="..." attribute to add a title to a code block.

    ```jsx title="src/components/HelloCodeBlockTitle.tsx"
    const HelloCodeBlockTitle = props => {
      return <h1>Hello CodeBlock Title</h1>;
    };
    ```

    It will be rendered as:

    src/components/HelloCodeBlockTitle.tsx
    const HelloCodeBlockTitle = props => {
      return <h1>Hello CodeBlock Title</h1>;
    };

    File code block

    You can use the file="./path/to/file" attribute without writing any code block content to reference the text from an external file.

    Relative paths

    Use relative paths starting with ./ or ../ to reference files relative to the current MDX file:

    foo.mdx
    _tsx-component.tsx
    ```tsx file="./_tsx-component.tsx"
    
    ```

    It will be rendered as:

    import { useState } from 'react';
    
    export default () => {
      const [count, setCount] = useState(0);
      return (
        <p>
          This is a component from tsx{' '}
          <button onClick={() => setCount(count => count + 1)}>{count}</button>
        </p>
      );
    };
    

    Absolute paths with / prefix

    Use the / prefix to reference files using absolute paths relative to the docs directory. This is useful when you need to reference shared code files from different locations in your documentation:

    ```tsx file="/components/Button.tsx"
    
    ```

    For example, if your docs directory is /project/docs, then /components/Button.tsx will resolve to /project/docs/components/Button.tsx.

    Absolute paths with <root>/ prefix

    Use the <root>/ prefix to reference files using absolute paths relative to the project root directory. This is useful when you need to reference shared code files from different locations in your documentation:

    ```tsx file="<root>/src/components/Button.tsx"
    
    ```

    For example, if your project root is /project, then <root>/src/components/Button.tsx will resolve to /project/src/components/Button.tsx.

    Tip

    When using external file code blocks, it's common to use them together with route conventions. Name files starting with _.

    Notation line highlight

    You can use Shiki transformers with the transformerNotationHighlight and // [!code highlight] comments to highlight code lines.

    Code
    rspress.config.ts
    ```ts
    console.log('Highlighted'); // [!code highlight]
    console.log('Not highlighted');
    // [!code highlight:2]
    console.log('Highlighted');
    console.log('Highlighted');
    ```

    It will be rendered as:

    highlight.ts
    console.log('Highlighted'); 
    console.log('Not highlighted');
    console.log('Highlighted');
    console.log('Highlighted');

    Meta line highlight

    Warning

    When using meta info for line highlighting, be aware that formatting tools may change line numbers. For maintainability, Notation Line Highlight is recommended.

    You can use @rspress/core/shiki-transformers with transformerCompatibleMetaHighlight and meta info comments to highlight code lines.

    Code
    rspress.config.ts
    ```ts {1,3-4}
    console.log('Highlighted');
    console.log('Not highlighted');
    console.log('Highlighted');
    console.log('Highlighted');
    ```

    It will be rendered as:

    console.log('Highlighted');
    console.log('Not highlighted');
    console.log('Highlighted');
    console.log('Highlighted');

    Show code line numbers

    You can show line numbers for individual code blocks using the lineNumbers meta attribute:

    ```ts lineNumbers
    function hello() {
      console.log('Line numbers enabled for this block');
    }
    ```

    It will be rendered as:

    function hello() {
      console.log('Line numbers enabled for this block');
    }

    You can also enable line numbers globally by setting the showLineNumbers option in the config file:

    rspress.config.ts
    export default {
      // ...
      markdown: {
        showLineNumbers: true,
      },
    };

    When showLineNumbers is enabled globally, all code blocks will show line numbers by default. You can disable line numbers for a specific code block by using lineNumbers=false:

    ```ts lineNumbers=false
    function hello() {
      console.log('Line numbers disabled for this block');
    }
    ```

    Wrap code

    You can enable code wrapping for individual code blocks using the wrapCode meta attribute:

    ```ts wrapCode
    const longLine = 'This is a very long line of code that will wrap when the wrapCode meta attribute is present';
    ```

    It will be rendered as:

    const longLine = 'This is a very long line of code that will wrap when the wrapCode meta attribute is present';

    You can also enable code wrapping globally by setting the defaultWrapCode option in the config file:

    rspress.config.ts
    export default {
      // ...
      markdown: {
        defaultWrapCode: true,
      },
    };

    When defaultWrapCode is enabled globally, all code blocks will wrap long lines by default. You can disable code wrapping for a specific code block by using wrapCode=false:

    ```ts wrapCode=false
    const longLine = 'This code block will not wrap even if defaultWrapCode is enabled globally';
    ```

    Code block height

    You can control the height behavior of code blocks using the height and fold meta attributes. There are three cases:

    • fold: Collapsible code block with an expand button. Height defaults to 300px.
    • height=X: Fixed height with vertical scrollbar. If combined with fold, the code block will be collapsible at the specified height instead.
    • No meta: Fully expanded by default. You can change this globally via markdown.defaultCodeOverflow.

    Fold

    Use the fold attribute to enable expand/collapse functionality. You can also customize the collapsed height via the height attribute (in pixels, default 300):

    ```tsx fold height="350"
    // Put longer code content here to trigger expand/collapse
    ```

    It will be rendered as:

    fold-demo.tsx
    import { useState } from 'react';
    
    export default () => {
      const [count, setCount] = useState(0);
      return (
        <div>
          <div>Line 1</div>
          <div>Line 2</div>
          <div>Line 3</div>
          <div>Line 4</div>
          <div>Line 5</div>
          <div>Line 6</div>
          <div>Line 7</div>
          <div>Line 8</div>
          <div>Line 9</div>
          <div>Line 10</div>
          <div>Line 11</div>
          <div>Line 12</div>
          <div>Line 13</div>
          <div>Line 14</div>
          <div>Line 15</div>
          <div>Line 16</div>
          <div>Line 17</div>
          <div>Line 18</div>
          <div>Line 19</div>
          <div>Line 20</div>
          <div>{count}</div>
          <button onClick={() => setCount(c => c + 1)}>{count}</button>
        </div>
      );
    };
    Tip

    The expand/collapse button will not be shown when the actual content height is less than height.

    Scroll

    Use the height attribute alone (without fold) to set a fixed height with a vertical scrollbar:

    ```tsx height="200"
    // Put longer code content here to trigger scrolling
    ```

    It will be rendered as:

    scroll-demo.tsx
    const lines = Array.from({ length: 20 }, (_, index) => `Line ${index + 1}`);
    
    export default function ScrollDemo() {
      return (
        <div>
          {lines.map(line => (
            <div key={line}>{line}</div>
          ))}
        </div>
      );
    }

    Combining meta attributes

    You can combine multiple meta attributes together:

    ```ts lineNumbers wrapCode title="example.ts"
    const longLine = 'This code block has line numbers, code wrapping, and a title';
    ```

    It will be rendered as:

    example.ts
    const longLine = 'This code block has line numbers, code wrapping, and a title';

    Diff code block

    ```diff
    function test() {
    - console.log('deleted');
    + console.log('added');
      console.log('unchanged');
    }
    ```

    It will be rendered as:

    function test() {
    - console.log('deleted');
    + console.log('added');
      console.log('unchanged');
    }

    Shiki transformers

    Rspress uses Shiki for compile-time code highlighting, providing flexible code block capabilities.

    You can add custom shiki transformers via markdown.shiki.transformers for richer code block effects.

    In addition to the transformerNotationHighlight mentioned above, Rspress defaults to supporting the following transformers from @shikijs/transformers.

    transformerNotationDiff

    Syntax
    rspress.config.ts
    ```ts
    console.log('deleted'); // [!code --]
    console.log('added'); // [!code ++]
    console.log('unchanged');
    ```

    It will be rendered as:

    console.log('deleted'); 
    console.log('added'); 
    console.log('unchanged');

    transformerNotationErrorLevel

    Syntax
    rspress.config.ts
    ```ts
    console.log('No errors or warnings');
    console.error('Error'); // [!code error]
    console.warn('Warning'); // [!code warning]
    ```

    It will be rendered as:

    console.log('No errors or warnings');
    console.error('Error'); 
    console.warn('Warning'); 

    transformerNotationFocus

    Syntax
    rspress.config.ts
    ```ts
    console.log('Not focused');
    console.log('Focused'); // [!code focus]
    console.log('Not focused');
    ```

    It will be rendered as:

    console.log('Not focused');
    console.log('Focused'); 
    console.log('Not focused');

    Twoslash

    Twoslash is a markup format for TypeScript code, suitable for creating self-contained code samples and letting the TypeScript compiler automatically supplement type information and hints. It is widely used on the official TypeScript website.

    Rspress provides the @rspress/plugin-twoslash plugin, which enables Twoslash features in Rspress. See @rspress/plugin-twoslash documentation for details.

    const str: string = 1;
    Type 'number' is not assignable to type 'string'.

    Runtime syntax highlighting

    When you need to render code blocks dynamically at runtime, such as in interactive docs or fetching code remotely, Rspress provides the CodeBlockRuntime component.

    Here is an example:

    foo.mdx
    import { CodeBlockRuntime } from '@rspress/core/theme';
    import { transformerNotationHighlight } from '@shikijs/transformers';
    
    <CodeBlockRuntime
      lang="ts"
      title="highlight.ts"
      code={`console.log('Highlighted'); // [!code highlight]
    // [!code highlight:1]
    console.log('Highlighted');
    console.log('Not highlighted');`}
      shikiOptions={{
        transformers: [transformerNotationHighlight()],
      }}
    />
    highlight.ts
    console.log('Highlighted'); // [!code highlight]
    // [!code highlight:1]
    console.log('Highlighted');
    console.log('Not highlighted');
    Warning

    It is recommended to use CodeBlockRuntime only when necessary, as it increases runtime bundle size and cannot benefit from compile-time highlighting performance.