CodeBlock
Displays syntax-highlighted source code with optional line numbers, toolbar, copy-to-clipboard button, and error diagnostics.
const beep = 'boop'import { CodeBlock } from 'renoun' export function Basic() { return <CodeBlock language="ts">const beep = 'boop'</CodeBlock> }
Supports both static code strings and custom rendering via Tokens, LineNumbers, and Toolbar subcomponents. For JavaScript and TypeScript, code can be type-checked, formatted with Prettier (if available), and augmented with quick-info tooltips on hover.
In development, the component uses a Suspense fallback to render immediately while asynchronous syntax highlighting and analysis load in the background. In production, it renders the fully-resolved code block directly.
Component Overrides
The CodeBlock component supports a components prop to override any of the internal elements (such as Container, Toolbar, Pre, LineNumbers, Tokens, CopyButton, and Code). In most cases, its a good idea to create your own component that wraps the CodeBlock component and applies the overrides you need:
import { type CodeBlockProps, CodeBlock as DefaultCodeBlock, Toolbar } from 'renoun'
import styles from './CodeBlock.module.css'
export function CodeBlock(props: CodeBlockProps) {
return (
<DefaultCodeBlock
{...props}
components={{
Container: (containerProps) => (
<div {...containerProps} className={styles.container} />
),
Toolbar: (toolbarProps) => (
<Toolbar {...toolbarProps} className={styles.toolbar} />
),
}}
/>
)
}If you need more customization, the CodeBlock component can be fully overridden by importing it from renoun and extending it as needed:
import {
type CodeBlockProps,
CodeBlock as DefaultCodeBlock,
Tokens,
} from 'renoun'
export function CodeBlock({
children,
...props
}: Omit<CodeBlockProps, 'children'> & { children: string }) {
return (
<DefaultCodeBlock {...props}>
<pre
style={{
whiteSpace: 'pre',
wordWrap: 'break-word',
overflow: 'auto',
}}
>
<Tokens>{children}</Tokens>
</pre>
</DefaultCodeBlock>
)
}Formatting
The CodeBlock source text is formatted by default using prettier if it is installed within the workspace. The shouldFormat prop can be used to disable this behavior:
<CodeBlock language="ts" shouldFormat={false}>
const foo = 'bar'
</CodeBlock>Examples
Type Checking
View Sourceconst a = 1 a + b Cannot find name 'b'. (2304)import { CodeBlock } from 'renoun' export function TypeChecking() { return ( <CodeBlock language="ts" showErrors> const a = 1; a + b; </CodeBlock> ) }
File System
View Source./counter/useCounter.ts'use client' import { useState } from 'react' export function useCounter(initialValue: number = 0) { const [count, setCount] = useState(initialValue) return { count, increment: () => setCount(count + 1), decrement: () => setCount(count - 1), } }import { CodeBlock } from 'renoun' export function FileSystem() { return ( <CodeBlock path="./counter/useCounter.ts" baseDirectory={import.meta.url} /> ) }
Ordered
View Sourceexample.tsconst a = 1example.tsconst a = 1 const b = 2import { CodeBlock } from 'renoun' export function Ordered() { return ( <div style={{ display: 'grid', gap: '2rem' }}> <CodeBlock path="01.example.ts">const a = 1;</CodeBlock> <CodeBlock path="02.example.ts">const a = 1; const b = 2;</CodeBlock> </div> ) }
Line Numbering
View Sourceline-numbers.ts1 2 3 4 5
const a = 1 const b = 2 const add = a + b const subtract = a - bimport { CodeBlock } from 'renoun' export function LineNumbering() { return ( <CodeBlock path="line-numbers.ts" showLineNumbers highlightedLines="4"> {`const a = 1;\nconst b = 2;\n\nconst add = a + b\nconst subtract = a - b`} </CodeBlock> ) }
Line Highlighting
View Sourceline-highlight.tsconst a = 1 const b = 2 const add = a + b const subtract = a - bimport { CodeBlock } from 'renoun' export function LineHighlighting() { return ( <CodeBlock path="line-highlight.ts" highlightedLines="2, 4"> {`const a = 1;\nconst b = 2;\n\nconst add = a + b\nconst subtract = a - b`} </CodeBlock> ) }
Line Focusing
View Sourceline-focus.tsconst a = 1 const b = 2 const add = a + b const subtract = a - bimport { CodeBlock } from 'renoun' export function LineFocusing() { return ( <CodeBlock path="line-focus.ts" focusedLines="2, 4"> {`const a = 1;\nconst b = 2;\n\nconst add = a + b\nconst subtract = a - b`} </CodeBlock> ) }
Line Highlight and Focus
View Sourceline-highlight-and-focus.tsconst a = 1 const b = 2 const add = a + b const subtract = a - bimport { CodeBlock } from 'renoun' export function LineHighlightAndFocus() { return ( <CodeBlock path="line-highlight-and-focus.ts" highlightedLines="2, 4" focusedLines="2, 4" > {`const a = 1;\nconst b = 2;\n\nconst add = a + b\nconst subtract = a - b`} </CodeBlock> ) }
Annotations
View Sourceimport { createContext } from 'react' const ThemeContext = createContext('light') const AuthContext = createContext(null)import { CodeBlock } from 'renoun' export function Annotations() { return ( <CodeBlock language="ts" annotations={{ mark: ({ children }) => ( <mark style={{ padding: '0 0.05em', borderRadius: '0.25rem', backgroundColor: 'rgb(164 146 234 / 20%)', boxShadow: '0px 0px 0 1px rgb(182 149 207)', color: 'inherit', }} > {children} </mark> ), }} > {` import { createContext } from 'react'; const /*mark*/ThemeContext/**mark*/ = createContext(/*mark*/'light'/**mark*/); const /*mark*/AuthContext/**mark*/ = createContext(/*mark*/null/**mark*/); `} </CodeBlock> ) }
Tokens Only
View Sourceconst a = 1 const b = 2 a + b
import { Tokens } from 'renoun' export function TokensOnly() { return ( <pre> <Tokens language="ts">{`const a = 1\nconst b = 2\na + b`}</Tokens> </pre> ) }
Custom Styles
View Source./counter/Counter.tsx'use client' import { useCounter } from './useCounter' export default function Counter({ initialCount }: { initialCount: number }) { const { count, decrement, increment } = useCounter(initialCount) return ( <div> <button onClick={decrement}>-</button> <span>{count}</span> <button onClick={increment}>+</button> </div> ) }import { CodeBlock, LineNumbers, Tokens, Toolbar } from 'renoun' export async function CustomStyles() { return ( <CodeBlock path="./counter/Counter.tsx" baseDirectory={import.meta.url}> <div style={{ fontSize: '1rem', borderRadius: '0.25rem', boxShadow: '0 0 0 1px var(--color-separator)', }} > <Toolbar allowCopy css={{ padding: '0.5lh', boxShadow: 'inset 0 -1px 0 0 var(--color-separator)', }} /> <pre style={{ display: 'grid', gridTemplateColumns: 'min-content max-content', padding: '0.5lh 0', lineHeight: 1.4, whiteSpace: 'pre', wordWrap: 'break-word', overflow: 'auto', }} > <LineNumbers css={{ padding: '0 0.5lh', backgroundColor: 'var(--color-background)', }} /> <code style={{ paddingRight: '0.5lh' }}> <Tokens /> </code> </pre> </div> </CodeBlock> ) }
API Reference
Properties
| Property | Type | Modifiers |
|---|---|---|
| path? | PathLike | — |
Name or path of the code block. Ordered file names will be stripped from the name e.g. | ||
| baseDirectory? | PathLike | — |
The base directory to use when analyzing the source code. This will read the local file system contents from the | ||
| language? | Languages | — |
Language of the source code provided to the | ||
| highlightedLines? | string | — |
A string of comma separated lines and ranges to highlight e.g. | ||
| focusedLines? | string | — |
A string of comma separated lines and ranges to focus e.g. | ||
| unfocusedLinesOpacity? | number | — |
Opacity of unfocused lines when using | ||
| allowCopy? | boolean | string | — |
Show or hide a button that copies the source code to the clipboard. Accepts a boolean or a string that will be copied. | ||
| allowErrors? | boolean | string | — |
Whether or not to allow errors. Accepts a boolean or comma-separated list of allowed error codes. | ||
| showErrors? | boolean | — |
Show or hide error diagnostics. | ||
| showLineNumbers? | boolean | — |
Show or hide line numbers. | ||
| showToolbar? | boolean | — |
Show or hide the toolbar. | ||
| shouldAnalyze? | boolean | — |
Whether or not to analyze the source code for type errors and provide quick information on hover. | ||
| shouldFormat? | boolean | — |
Whether or not to format the source code using | ||
| annotations? | AnnotationRenderers | — |
Annotation renderers used to transform inline or block annotations. | ||
| components? | Partial<CodeBlockComponentOverrides> | — |
Override the default component renderers. | ||
Properties
| Property | Type | Modifiers |
|---|---|---|
| Container | SlotComponentOrProps<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & { css?: CSSObject; }> | — |
| Toolbar | SlotComponentOrProps<ToolbarProps> | — |
| Pre | SlotComponentOrProps<React.ClassAttributes<HTMLPreElement> & React.HTMLAttributes<HTMLPreElement> & { css?: CSSObject; }> | — |
| LineNumbers | SlotComponentOrProps<LineNumbersProps> | — |
| Code | SlotComponentOrProps<React.ClassAttributes<HTMLElement> & React.HTMLAttributes<HTMLElement> & { css?: CSSObject; }> | — |
| Tokens | SlotComponentOrProps<TokensProps> | — |
| CopyButton | SlotComponentOrProps<{ value?: string | ((event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => string); css?: CSSObject; } & Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "value">> | — |
Properties
| Property | Type | Modifiers |
|---|---|---|
| Container | React.ComponentType<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & { css?: CSSObject; }> | — |
| Toolbar | React.ComponentType<ToolbarProps> | — |
| Pre | React.ComponentType<React.ClassAttributes<HTMLPreElement> & React.HTMLAttributes<HTMLPreElement> & { css?: CSSObject; }> | — |
| LineNumbers | React.ComponentType<LineNumbersProps> | — |
| Code | React.ComponentType<React.ClassAttributes<HTMLElement> & React.HTMLAttributes<HTMLElement> & { css?: CSSObject; }> | — |
| Tokens | React.ComponentType<TokensProps> | — |
| CopyButton | React.ComponentType<{ value?: string | ((event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => string); css?: CSSObject; } & Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "value">> | — |
Type
CodeBlockBaseProps & { children: React.ReactNode; } | CodeBlockBaseProps & { children?: React.ReactNode; path: PathLike; }Displays syntax-highlighted source code with optional line numbers, toolbar, copy-to-clipboard button, and error diagnostics.
Properties
CodeBlockProps | React.DetailedHTMLProps<React.HTMLAttributes<HTMLPreElement>, HTMLPreElement>Returns
React.JSX.Element | Promise<React.JSX.Element>Modifiers
async