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.
Style Overrides
The CodeBlock component can be styled using the, css, className, and style props to target specific descendant components. In most cases, its a good idea to create your own component that wraps the CodeBlock component and applies the style overrides you need:
import {
type CodeBlockProps,
CodeBlock as DefaultCodeBlock,
Tokens,
} from 'renoun'
import styles from './CodeBlock.module.css'
export function CodeBlock(props: CodeBlockProps) {
return (
<DefaultCodeBlock
{...props}
css={{
// Clear the default styles
container: {
boxShadow: undefined,
borderRadius: undefined,
},
...props.css,
}}
className={{
container: styles.container,
token: styles.token,
...props.className,
}}
/>
)
}
Component Overrides
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 | |
|---|---|---|
| path? | string | |
| baseDirectory? | string | |
| language? | Languages | |
| highlightedLines? | string | |
| focusedLines? | string | |
| unfocusedLinesOpacity? | number | |
| allowCopy? | boolean | string | |
| allowErrors? | boolean | string | |
| showErrors? | boolean | |
| showLineNumbers? | boolean | |
| showToolbar? | boolean | |
| shouldAnalyze? | boolean | |
| shouldFormat? | boolean | |
| annotations? | AnnotationRenderers | |
| css? | { container?: CSSObject | undefined; toolbar?: CSSObject | undefined; lineNumbers?: CSSObject | undefined; token?: CSSObject | undefined; popover?: CSSObject | undefined; error?: CSSObject | undefined; copyButton?: CSSObject | undefined; } | |
| className? | { container?: string | undefined; toolbar?: string | undefined; lineNumbers?: string | undefined; token?: string | undefined; popover?: string | undefined; error?: string | undefined; copyButton?: string | undefined; } | |
| style? | { container?: CSSProperties | undefined; toolbar?: CSSProperties | undefined; lineNumbers?: CSSProperties | undefined; token?: CSSProperties | undefined; popover?: CSSProperties | undefined; error?: CSSProperties | undefined; copyButton?: CSSProperties | undefined; } | |
Type
CodeBlockBaseProps & { children: ReactNode; } | CodeBlockBaseProps & { children?: ReactNode; path: string; }Displays syntax-highlighted source code with optional line numbers, toolbar, copy-to-clipboard button, and error diagnostics.
Properties
CodeBlockPropsParses the props of an MDX pre element for passing to CodeBlock.
function parsePreProps(props: React.ComponentProps<'pre'>): { children: string; language?: Languages | undefined; path?: string | undefined; } & Omit<DetailedHTMLProps<HTMLAttributes<HTMLPreElement>, HTMLPreElement>, "style" | "children" | "className">Parameters
| Parameter | Type | Default Value |
|---|---|---|
| props | DetailedHTMLProps<HTMLAttributes<HTMLPreElement>, HTMLPreElement> | — |
Returns
{ children: string; language?: Languages | undefined; path?: string | undefined; } & Omit<DetailedHTMLProps<HTMLAttributes<HTMLPreElement>, HTMLPreElement>, "style" | "children" | "className">