Skip to content
+

Chat - Code Blocks

Display code with a language label and copy-to-clipboard button using the ChatCodeBlock component.

ChatCodeBlock renders fenced code blocks with a header bar showing the language label and a one-click copy button.

Import

import { ChatCodeBlock } from '@mui/x-chat';

Automatic rendering in chat

When using ChatBox, any code fence in a markdown assistant message is automatically rendered as a ChatCodeBlock. No extra configuration is needed — the built-in renderMarkdown function emits ChatCodeBlock for every code fence it encounters.

```python
def greet(name):
    return f"Hello, {name}!"
```

The language specified after the opening backticks (for example, python) appears in the header bar.

MUI Assistant
Material UI chat
Styled with your active MUI theme
Material UI chat

Styled with your active MUI theme

You
You

Write me a Python function to flatten a nested list.

MUI Assistant
MUI Assistant

Here's a recursive Python function that flattens a nested list:

python
def flatten(lst):
    result = []
    for item in lst:
        if isinstance(item, list):
            result.extend(flatten(item))
        else:
            result.append(item)
    return result

It works by iterating over each item — if the item is itself a list it recurses, otherwise it appends the value directly.

Standalone with custom highlighter
python
def flatten(lst):
    result = []
    for item in lst:
        if isinstance(item, list):
            result.extend(flatten(item))
        else:
            result.append(item)
    return result

Standalone usage

Use ChatCodeBlock as a standalone component by passing children (the code string) and an optional language:

<ChatCodeBlock language="typescript">
  {`const greet = (name: string) => \`Hello, \${name}!\`;`}
</ChatCodeBlock>

Copy button

Clicking the copy button copies the raw code string to the clipboard and shows a check mark icon for 2 seconds. The copy behavior uses the Clipboard API (navigator.clipboard.writeText).

Language label

Set language to any string — it is displayed as-is in the header:

<ChatCodeBlock language="bash">{`pnpm add @mui/x-chat`}</ChatCodeBlock>

When no language is provided, the header still renders but the label area is empty.

Syntax highlighting

ChatCodeBlock intentionally does not bundle a syntax-highlighting library. Pass a highlighter function to integrate your preferred library (Shiki, Prism, highlight.js, etc.):

import { ChatCodeBlock } from '@mui/x-chat';
import { codeToHtml } from 'shiki';

function ShikiBlock({ code, language }) {
  const [html, setHtml] = React.useState('');

  React.useEffect(() => {
    codeToHtml(code, { lang: language, theme: 'github-light' }).then(setHtml);
  }, [code, language]);

  return (
    <ChatCodeBlock
      language={language}
      highlighter={() => <span dangerouslySetInnerHTML={{ __html: html }} />}
    >
      {code}
    </ChatCodeBlock>
  );
}

The highlighter prop receives (code, language) and should return React nodes. When omitted, the raw code string is displayed with no highlighting.

Customizing rendering in ChatBox

To customize how code fences render inside ChatBox, override partProps.text.renderText on ChatMessageContent with a custom markdown renderer that uses your own code block component:

<ChatBox
  adapter={adapter}
  slotProps={{
    messageContent: {
      partProps: {
        text: {
          renderText: (text) => <MyMarkdownWithCustomCodeBlocks content={text} />,
        },
      },
    },
  }}
/>

CSS classes

Class name Description
.MuiChatCodeBlock-root Root container
.MuiChatCodeBlock-header Header bar
.MuiChatCodeBlock-languageLabel Language label text
.MuiChatCodeBlock-copyButton Copy-to-clipboard button
.MuiChatCodeBlock-pre Pre element wrapper
.MuiChatCodeBlock-code Code element

See also

API

See the documentation below for a complete reference to all of the props and classes available to the components mentioned here.