

# CodeBlock

Code display with copy-to-clipboard, line numbers, and optional syntax highlighting.

`CodeBlock` handles layout and interaction. **Syntax highlighting is separate** — you run a
highlighter (highlight.js, Shiki, Prism, etc.) and pass the result via `codeHtml` and
`codeClassName`. The plain `code` string is always used for the copy button.

## Examples

### Default

```tsx
import { CodeBlock } from '@var-ui/react';

const code = 'const greeting = "hello";';

<CodeBlock
  code={code}
  language="tsx"
  codeHtml={/* from your highlighter */}
  codeClassName="hljs language-tsx"
/>
```

```astro
---
import { CodeBlock } from '@var-ui/astro';

const code = 'const greeting = "hello";';
---

<CodeBlock
  code={code}
  language="tsx"
  codeHtml={/* from your highlighter */}
  codeClassName="hljs language-tsx"
/>
```

```html
<div class="var-ui-code-block var-ui-code-block__rootDefault" data-codeblock><div class="var-ui-code-block__header" data-codeblock-header><div class="var-ui-code-block__title"><span class="var-ui-code-block__language">tsx</span></div></div><div class="var-ui-code-block__body var-ui-code-block__bodyScrollable" data-codeblock-body><pre class="var-ui-code-block__pre var-ui-code-block__preScrollX" data-codeblock-pre><code class="var-ui-code-block__code">const greeting = "hello";</code></pre></div></div>
```

## Syntax highlighting

### Styles

Syntax highlighting colors come from `color.code` tokens (`--var-ui-color-code-*`).
Your app maps those CSS variables to whatever highlighter you use — highlight.js
class selectors, a Shiki theme, Prism tokens, etc. See
[Design tokens](/theming/tokens#syntax-highlighting).

### Runtime highlighting

Pass pre-highlighted HTML alongside the plain source:

```tsx
import { CodeBlock } from '@var-ui/react';
import hljs from 'highlight.js/lib/core';
import typescript from 'highlight.js/lib/languages/typescript';

hljs.registerLanguage('typescript', typescript);

const code = 'const greeting = "hello";';

<CodeBlock
  code={code}
  language="tsx"
  codeHtml={hljs.highlight(code, { language: 'typescript' }).value}
  codeClassName="hljs language-typescript"
/>;
```

Use any highlighter that outputs HTML with `hljs-*` classes (or map your classes to the
same token groups in a custom theme).

### Build-time highlighting

For docs sites and SSR, prefer highlighting at build time — Shiki, `rehype-highlight`, or
Astro/MDX pipelines — then pass the resulting HTML to `codeHtml`. No client-side highlighter
bundle required.

### Line numbers

When `showLineNumbers` is enabled, pass one HTML string per line via `lineHtml` instead of
`codeHtml`:

```tsx
const lines = code.replace(/\n$/, '').split('\n');

<CodeBlock
  code={code}
  language="tsx"
  showLineNumbers
  lineHtml={lines.map((line) => hljs.highlight(line, { language: 'typescript' }).value)}
/>;
```

## Props

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| code | string | yes |  | Source code string to display and copy. |
| className | string \| undefined | no |  | Additional CSS class names merged onto the root element. |
| codeClassName | string \| undefined | no |  | Classes for the highlighted `<code>` element (e.g. `hljs language-tsx`). |
| codeHtml | string \| undefined | no |  | Pre-highlighted HTML for the code body. Pair with `codeClassName` from your highlighter. |
| copiedLabel | string \| undefined | no | Copied | Feedback text after a successful copy. |
| copyable | boolean \| undefined | no | true | Whether to show the copy-to-clipboard button. |
| copyErrorLabel | string \| undefined | no | Copy failed | Feedback text when clipboard write fails. |
| copyLabel | string \| undefined | no | Copy code | Accessible label for the copy button. |
| filename | string \| undefined | no |  | Optional filename shown in the header. |
| highlightedLines | number[] \| undefined | no |  | 1-based line numbers to highlight. |
| language | string \| undefined | no |  | Language tag shown in the header (e.g. `tsx`, `bash`). |
| lineHtml | string[] \| undefined | no |  | Pre-highlighted HTML per line when `showLineNumbers` is enabled. |
| showLineNumbers | boolean \| undefined | no | false | Show line numbers in a gutter column. |
| variant | CodeBlockVariant \| undefined | no | default | Visual variant of the code block. |
| wrapLongLines | boolean \| undefined | no | false | Wrap long lines instead of horizontal scrolling. |

## Accessibility

Built on React Aria Components where applicable.
