Code Block
The CodeBlock
component provides syntax highlighting, line numbers, and copy to clipboard functionality for code blocks.
function MyComponent(props) {
return (
<div>
<h1>Hello, {props.name}!</h1>
<p>This is an example React component.</p>
</div>
);
}
function MyComponent(props) {
return (
<div>
<h1>Hello, {props.name}!</h1>
<p>This is an example React component.</p>
</div>
);
}
Installation
npx ai-elements@latest add code-block
Usage
import { CodeBlock, CodeBlockCopyButton } from '@/components/ai-elements/code-block';
<CodeBlock data={"console.log('hello world')"} language="jsx"> <CodeBlockCopyButton onCopy={() => console.log('Copied code to clipboard')} onError={() => console.error('Failed to copy code to clipboard')} /></CodeBlock>
Usage with AI SDK
CodeBlock
will automatically render within
Response
.
Build a simple code generation tool using the experimental_useObject
hook.
Add the following component to your frontend:
app/page.tsx
'use client';
import { experimental_useObject as useObject } from '@ai-sdk/react';import { codeBlockSchema } from '@/app/api/codegen/route';import { Input, PromptInputTextarea, PromptInputSubmit,} from '@/components/ai-elements/prompt-input';import { CodeBlock, CodeBlockCopyButton,} from '@/components/ai-elements/code-block';import { useState } from 'react';
export default function Page() { const [input, setInput] = useState(''); const { object, submit, isLoading } = useObject({ api: '/api/codegen', schema: codeBlockSchema, });
const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (input.trim()) { submit(input); } };
return ( <div className="max-w-4xl mx-auto p-6 relative size-full rounded-lg border h-[600px]"> <div className="flex flex-col h-full"> <div className="flex-1 overflow-auto mb-4"> {object?.code && object?.language && ( <CodeBlock code={object.code} language={object.language} showLineNumbers={true} > <CodeBlockCopyButton /> </CodeBlock> )} </div>
<Input onSubmit={handleSubmit} className="mt-4 w-full max-w-2xl mx-auto relative" > <PromptInputTextarea value={input} placeholder="Generate a React todolist component" onChange={(e) => setInput(e.currentTarget.value)} className="pr-12" /> <PromptInputSubmit status={isLoading ? 'streaming' : 'ready'} disabled={!input.trim()} className="absolute bottom-1 right-1" /> </Input> </div> </div> );}
Add the following route to your backend:
api/codegen/route.ts
import { streamObject } from 'ai';import { z } from 'zod';
export const codeBlockSchema = z.object({ language: z.string(), filename: z.string(), code: z.string(),});// Allow streaming responses up to 30 secondsexport const maxDuration = 30;
export async function POST(req: Request) { const context = await req.json();
const result = streamObject({ model: 'openai/gpt-4o', schema: codeBlockSchema, prompt: `You are a helpful coding assitant. Only generate code, no markdown formatting or backticks, or text.` + context, });
return result.toTextStreamResponse();}
Features
- Syntax highlighting with react-syntax-highlighter
- Line numbers (optional)
- Copy to clipboard functionality
- Automatic light/dark theme switching
- Customizable styles
- Accessible design
Examples
Dark Mode
To use the CodeBlock
component in dark mode, you can wrap it in a div
with the dark
class.
function MyComponent(props) {
return (
<div>
<h1>Hello, {props.name}!</h1>
<p>This is an example React component.</p>
</div>
);
}
function MyComponent(props) {
return (
<div>
<h1>Hello, {props.name}!</h1>
<p>This is an example React component.</p>
</div>
);
}
Props
<CodeBlock />
code:
string
The code content to display.
language:
string
The programming language for syntax highlighting.
showLineNumbers?:
boolean
Whether to show line numbers. Default: false.
children?:
React.ReactNode
Child elements (like CodeBlockCopyButton) positioned in the top-right corner.
className?:
string
Additional CSS classes to apply to the root container.
[...props]?:
React.HTMLAttributes<HTMLDivElement>
Any other props are spread to the root div.
<CodeBlockCopyButton />
onCopy?:
() => void
Callback fired after a successful copy.
onError?:
(error: Error) => void
Callback fired if copying fails.
timeout?:
number
How long to show the copied state (ms). Default: 2000.
children?:
React.ReactNode
Custom content for the button. Defaults to copy/check icons.
className?:
string
Additional CSS classes to apply to the button.
[...props]?:
React.ComponentProps<typeof Button>
Any other props are spread to the underlying shadcn/ui Button component.