Code Blocks
Use syntax highlighting (Shiki by default), titles, line numbers, word wrap, and copy buttons in Markdown code blocks.
Fenced code blocks in Boltdocs use Shiki by default for syntax highlighting, but the highlighting engine is pluggable — any engine implementing the CodeHighlighterAdapter contract can be selected through theme.codeHighlighting. Everything is computed at build time, ensuring fast load times with zero client-side performance cost.
Code Block Parameters (Meta Properties)
Boltdocs supports custom parameters on the code block header line to configure titles, line numbers, and word wrap dynamically.
1. Title Banner
Add title="file_name.extension" to display a styled header containing the file name. A generic file icon is rendered next to the title to indicate the code block boundary:
```tsx title="components/Button.tsx"
export const Button = () => <button>Click me</button>;
```
2. Line Numbers
Add showLineNumbers (or lineNumbers) to display line numbers next to your code:
```ts showLineNumbers
const num = 42;
console.log(num);
```
3. Word Wrap
Add wordWrap (or word-wrap) to break long code lines, avoiding the default horizontal scrollbar:
```css wordWrap
.very-long-class-selector-that-needs-to-wrap-rather-than-overflowing-and-creating-a-scrollbar {
color: red;
}
```
Combining Parameters
You can combine these attributes in any order:
```json title="package.json" showLineNumbers wordWrap
{
"name": "my-cool-package",
"version": "1.0.0",
"description": "A very descriptive paragraph that will wrap across multiple lines in the rendered code block output instead of causing horizontal scrollbars."
}
```
Configuration
You can customize the highlighting themes in boltdocs.config.ts. You can pick different themes for light and dark modes. Shiki is the default engine; set theme.codeHighlighting.engine to switch to a plugin-provided engine:
// boltdocs.config.ts
import { defineConfig } from 'boltdocs'
export default defineConfig({
theme: {
codeHighlighting: {
engine: 'shiki', // registry id, adapter instance, or factory
theme: {
light: 'github-light',
dark: 'github-dark',
},
// Faster dev-server startup — see Getting Started > Configuration.
options: { regexEngine: 'oniguruma' },
},
},
})
Supported Themes
The following syntax highlighting themes are supported out of the box:
github-light/github-darktokyo-nightdraculanordone-dark-proone-light
Enhanced Features
- Copy Code Button: A floating copy button is automatically added to the top-right corner of every code block.
- Word Wrap: Long code lines overflow cleanly with a scrollbar or wrap when the
wordWraporword-wrapparameter is set.
Customizing Code Blocks
If the default code block design, styling, or interactions don't fit your design system, you can easily build a fully custom code block component.
Boltdocs exposes the core state and logic of code blocks through the useCodeBlock hook, letting you focus purely on your custom visual rendering without rewriting the complex highlighted-HTML parsing, clipboard copy timers, expand/truncate logic, or feedback form integrations.
1. Registering a Custom Code Block
To override the default code block component, register your custom component as the renderer for the pre tag in your docs/mdx-components.tsx file:
import { CustomCodeBlock } from '../src/components/CustomCodeBlock'
export default {
pre: CustomCodeBlock,
}
2. Building a Custom Code Block Component
Use the useCodeBlock hook from 'boltdocs/client' to access the resolved code block state and wrap the output in the layout primitives imported from 'boltdocs/primitives':
import { useCodeBlock } from 'boltdocs/client'
import { CodeBlock } from 'boltdocs/primitives'
export function CustomCodeBlock(props) {
const {
preRef,
copied,
handleCopy,
effectiveTitle,
effectiveHighlightedHtml,
isExpandable,
isExpanded,
setIsExpanded,
shouldTruncate,
} = useCodeBlock(props)
return (
<CodeBlock plain={props.plain}>
{effectiveTitle && (
<CodeBlock.Header>
<CodeBlock.Group>
<span>{effectiveTitle}</span>
</CodeBlock.Group>
<button onClick={handleCopy}>
{copied ? 'Copied!' : 'Copy'}
</button>
</CodeBlock.Header>
)}
<CodeBlock.Content shouldTruncate={shouldTruncate}>
{effectiveHighlightedHtml ? (
<div
ref={preRef}
dangerouslySetInnerHTML={{ __html: effectiveHighlightedHtml }}
/>
) : (
<pre ref={preRef}>{props.children}</pre>
)}
{isExpandable && (
<button onClick={() => setIsExpanded(!isExpanded)}>
{isExpanded ? 'Show less' : 'Expand'}
</button>
)}
</CodeBlock.Content>
</CodeBlock>
)
}
3. Hook API Reference (useCodeBlock)
The useCodeBlock hook accepts the standard code block props (passed from the MDX compiler) and returns the following resolved state and properties:
| Property | Type | Description |
|---|---|---|
copied | boolean | true if the code was recently copied to the clipboard (resets after 2 seconds). |
handleCopy | () => void | Copies the current plain text content of the code block to the clipboard. |
isExpanded | boolean | true if an expandable code block is currently expanded. |
setIsExpanded | (val: boolean) => void | Updates the expanded state of the code block. |
isExpandable | boolean | true if the code block exceeds 6 lines and supports expand/truncate. |
shouldTruncate | boolean | Helper flag that is true when the block is expandable and not yet expanded. |
preRef | RefObject<HTMLElement> | A React Ref that MUST be attached to the container element rendering the code text or Shiki HTML. Used to read the text to copy and compute line counts. |
isHighlighted | boolean | true if the code block has syntax highlighting (e.g., via Shiki). |
effectiveHighlightedHtml | string | undefined | The preprocessed, cleaned syntax highlighting HTML string. Render using dangerouslySetInnerHTML if present. |
effectiveTitle | string | undefined | The resolved title from the code block meta parameters. |
lang | string | The parsed language identifier of the code block (e.g., 'ts', 'json'). |
showCodeBlockFeedback | boolean | true if code block feedback forms are enabled in boltdocs.config.ts and the block is not in plain mode. |
rated | 'up' | 'down' | null | The current feedback rating submitted by the user. |
handleRate | (type: 'up' | 'down') => Promise<void> | Callback function to submit the feedback rating to the serverless endpoint. |