---
type: doc
title: Code Block
description: Code and plain-text snippets with copy actions, line numbers and highlighted lines.
---

```astro title="src/components/examples/code-block/code-block-demo.astro"
---
import {
  CodeBlock,
  CodeBlockActions,
  CodeBlockContent,
  CodeBlockCopyButton,
  CodeBlockHeader,
  CodeBlockTitle,
} from "@/components/ui/code-block"

const code = `import { Button } from "@/components/ui/button"

<Button href="/contact/">Contact us</Button>`
---

<CodeBlock class="max-w-lg">
  <CodeBlockHeader>
    <CodeBlockTitle>contact.astro</CodeBlockTitle>
    <CodeBlockActions>
      <CodeBlockCopyButton value={code} />
    </CodeBlockActions>
  </CodeBlockHeader>
  <CodeBlockContent code={code} />
</CodeBlock>
```

## Installation

```bash
npx shadcn@latest add @fulldev/code-block
```

## Usage

```astro
---
import {
  CodeBlock,
  CodeBlockActions,
  CodeBlockContent,
  CodeBlockCopyButton,
  CodeBlockHeader,
  CodeBlockTitle,
} from "@/components/ui/code-block"

const code = "const greeting = 'Hello'"
---

<CodeBlock>
  <CodeBlockHeader>
    <CodeBlockTitle>greeting.ts</CodeBlockTitle>
    <CodeBlockActions>
      <CodeBlockCopyButton value={code} />
    </CodeBlockActions>
  </CodeBlockHeader>
  <CodeBlockContent code={code} />
</CodeBlock>
```

`CodeBlockContent` renders escaped text from `code`, or accepts composed
`CodeBlockLine` children in its slot. Code stays left to right inside an RTL
page. The content scrolls by keyboard; floating actions appear on hover,
focus and touch screens. Copying requires HTTPS or localhost.

## Line numbers

Set `lineNumbers` to split `code` into numbered lines. Use `startLine` for an
excerpt from the middle of a file. Numbers are CSS counters and are excluded
from copied text.

```astro title="src/components/examples/code-block/code-block-numbered.astro"
---
import { CodeBlock, CodeBlockContent } from "@/components/ui/code-block"

const code = `{
  "name": "our-website",

  "private": true
}`
---

<CodeBlock class="max-w-lg">
  <CodeBlockContent code={code} lineNumbers />
</CodeBlock>
```

## Highlighted lines and diffs

Import `CodeBlockLine` and set its `variant` to `highlighted`, `added` or
`removed`. Add `lineNumbers` to the content to number composed lines.
Diff markers are excluded from copied text. Empty lines preserve a newline.
Use string expressions inside composed lines to preserve indentation.

```astro title="src/components/examples/code-block/code-block-lines.astro"
---
import {
  CodeBlock,
  CodeBlockContent,
  CodeBlockLine,
} from "@/components/ui/code-block"
---

<CodeBlock class="max-w-lg">
  <CodeBlockContent lineNumbers startLine={12}>
    <CodeBlockLine>export const site = &#123;</CodeBlockLine>
    <CodeBlockLine variant="removed">{'  title: "Our website",'}</CodeBlockLine>
    <CodeBlockLine variant="added">
      {'  title: "Our new website",'}
    </CodeBlockLine>
    <CodeBlockLine />
    <CodeBlockLine variant="highlighted">{'  lang: "en",'}</CodeBlockLine>
    <CodeBlockLine>&#125;</CodeBlockLine>
  </CodeBlockContent>
</CodeBlock>
```

The component renders plain text by default. Syntax highlighting is optional:
pass server-highlighted token markup inside each `CodeBlockLine`. The React
`useHighlightedCode` hook is not needed in Astro.

## Wrapping and size

Long lines scroll by default. Set `wrap` on the content to wrap them, or add a
`max-h-*` class to limit the content height. Use `size="sm"` on `CodeBlock` for
a compact snippet, `variant="destructive"` for error output, and
`CodeBlockFooter` for a caption or additional actions.

Without a header, put `CodeBlockActions` directly inside `CodeBlock` for
floating actions.

```astro title="src/components/examples/code-block/code-block-wrap.astro"
---
import {
  CodeBlock,
  CodeBlockActions,
  CodeBlockContent,
  CodeBlockCopyButton,
  CodeBlockFooter,
} from "@/components/ui/code-block"

const code =
  "A long explanation can wrap inside a code block without making the surrounding article or the page scroll horizontally."
---

<CodeBlock size="sm" class="max-w-sm">
  <CodeBlockActions>
    <CodeBlockCopyButton value={code} />
  </CodeBlockActions>
  <CodeBlockContent code={code} wrap />
  <CodeBlockFooter>Plain text, with line wrapping.</CodeBlockFooter>
</CodeBlock>
```

## API Reference

Source: [`src/components/ui/code-block`](https://github.com/fulldotdev/ui/tree/main/src/components/ui/code-block)

| Component             | Props                                                                            | Default                |
| --------------------- | -------------------------------------------------------------------------------- | ---------------------- |
| `CodeBlock`           | `variant: "default" \| "destructive"`, `size: "default" \| "sm"`                 | `"default"`            |
| `CodeBlockContent`    | `code?: string`, `wrap?: boolean`, `lineNumbers?: boolean`, `startLine?: number` | `false`, `false`, `1`  |
| `CodeBlockLine`       | `variant: "default" \| "highlighted" \| "added" \| "removed"`                    | `"default"`            |
| `CodeBlockCopyButton` | `value: string`, Button `variant` and `size`                                     | `"ghost"`, `"icon-xs"` |

`CodeBlockCopyButton` also accepts `copyLabel`, `copiedLabel` and `errorLabel`
for translation. Its live region announces successful or failed copies, and
its success state resets after two seconds. Header, title, actions and footer
forward HTML attributes and `class` to their root.

## Install what this page shows

```bash
npx shadcn@latest add @fulldev/code-block-examples
```
