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>
  );
}

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 seconds
export 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>
  );
}

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.