Code Blocks
Use Shiki syntax highlighting, titles, line numbers, word-wrapping, and copying in Markdown code blocks.
Fenced code blocks in Boltdocs use Shiki for syntax highlighting. They are computed entirely at build time, ensuring fast page load speeds with zero client-side performance cost.
Usage
Create code blocks using standard markdown triple backticks. Specify the language identifier for highlighting support.
// Example: src/index.ts
export function greet(name: string): string {
return `Hello, ${name}!`
}
Code Block Parameters (Meta Properties)
Boltdocs supports custom parameters in the code block's header line to configure titles, line numbers, and word wrapping dynamically.
1. Title Banner
Add title="file_name.extension" to display a styled header containing the filename. 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 beside your code:
```ts showLineNumbers
const num = 42;
console.log(num);
```
3. Word Wrapping
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 onto multiple lines in the generated code block render rather than causing horizontal scrollbars."
}
```
Configuration
You can customize the Shiki themes in boltdocs.config.ts. You can choose different themes for light and dark modes:
// boltdocs.config.ts
import { defineConfig } from 'boltdocs'
export default defineConfig({
theme: {
codeTheme: {
light: 'github-light',
dark: 'github-dark',
},
},
})
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 Wrapping: Long code lines overflow cleanly with a scrollbar or wrap when the
wordWraporword-wrapparameter is set.
Customizing Code Blocks
If the default code block layout, styling, or interactions do not fit your design system, you can easily build a fully custom code block component.
Boltdocs exposes the core state and logic of code blocks via the useCodeBlock hook, allowing you to focus purely on your custom visual rendering without having to rewrite complex highlighted HTML parsing, clipboard copy timers, expansion and truncation logic, or feedback form integrations.
1. Registering a Custom Code Block
To override the default code block component, register your custom component as the pre tag renderer 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 properties (passed from the MDX compiler) and returns the following state and resolved 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 expansion state of the code block. |
isExpandable | boolean | true if the code block exceeds 6 lines and supports expansion/truncation. |
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 copy text and compute line counts. |
isHighlighted | boolean | true if the code block is syntax-highlighted (e.g. via Shiki). |
effectiveHighlightedHtml | string | undefined | The pre-processed and cleaned syntax-highlighted 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 feedback rating to the serverless endpoint. |