Data Display

Code Block

A syntax-highlighted code block with a copy button, a built-in lightweight tokenizer, and a line-by-line reveal animation.

A zero-dependency syntax-highlighted code block: it ships its own regex tokenizer (no shiki or prism required) and supports a filename header bar, line numbers, highlighting specific lines, one-click copy, and a line-by-line staggered fade in.

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add code-block.en

New project or installation trouble? Start here →

Code Block is a React syntax highlighting code block component built with Tailwind CSS and Motion, with lucide-react icons for the copy button. Highlighting is handled by a character-by-character tokenizer inside the file, so you do not need to install a separate highlighting package.

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

Active edited usageDefault props
<CodeBlock/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

When to use

  • Install commands and API call samples on a product site or landing page.
  • Short snippets in blog posts, technical articles or changelogs.
  • Step-by-step tutorials, using highlighted lines to mark what changed in each step.
  • "Integration settings" pages in a SaaS dashboard showing webhook samples or SDK setup code.

Installation

npx webberui@latest add https://webberui.com/r/code-block.en.json

Or, once registries are configured in components.json, install it as @webberui/code-block.

Usage

import { CodeBlock } from "@/components/ui/code-block";

<CodeBlock
  code={`const hello = "world";`}
  language="tsx"
  filename="example.tsx"
  showLineNumbers
/>

Supported language keywords: tsx, jsx, ts, js, python, bash, css, json, html. An unknown language falls back to a generic mode that still highlights strings, comments, and numbers.

Examples

Read a file in a Server Component

The component only needs a code string, so a Next.js Server Component can read an example file with fs and pass it to CodeBlock.

// app/docs/setup/page.tsx
import { readFile } from "node:fs/promises";
import { CodeBlock } from "@/components/ui/code-block";

export default async function SetupPage() {
  const code = await readFile("examples/client.ts", "utf8");

  return (
    <CodeBlock code={code} language="ts" filename="client.ts" showLineNumbers />
  );
}

Tutorial step with highlighted lines

highlightLines marks key lines by 1-based line number, and traffic adds a window header with red, yellow and green dots.

<CodeBlock
  language="tsx"
  filename="app/layout.tsx"
  traffic
  showLineNumbers
  highlightLines={[2, 7]}
  code={`import "./globals.css";
import { Toaster } from "@/components/ui/toaster";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}<Toaster /></body>
    </html>
  );
}`}
/>

Long output with a height limit and no animation

For long terminal output or config files, maxHeight makes the content area scroll and animate={false} renders it without the line-by-line fade.

<CodeBlock
  language="bash"
  filename="Terminal"
  animate={false}
  maxHeight={240}
  code={deployLog}
/>

Props

PropTypeDefaultDescription
codestring—The code string to display
languagestring"tsx"Language tag, which decides the keyword and comment syntax
filenamestring—Filename/title shown on the left of the header bar
showLineNumbersbooleanfalseWhether to show line numbers
highlightLinesnumber[][]Line numbers to highlight (1-based), given a background tint
copybooleantrueWhether to show the copy button
trafficbooleanfalseShow macOS-style red/yellow/green dots in the header bar
animatebooleantrueStagger a line-by-line fade in when it enters the viewport
maxHeightnumber—Maximum height of the content area (px); beyond it, the area scrolls

Accessibility

  • When the user has "reduce motion" enabled at the system level, it renders statically without applying the line-by-line animation
  • The copy button carries an aria-label, and after a successful copy it transitions smoothly between the copy and check icons
  • The first render matches SSR and the animation is only enabled after mount, which avoids a hydration mismatch

FAQ

Does it work with the Next.js App Router?

Yes. The file starts with "use client", so import it from a Server Component page as usual, and pass strings you read on the server straight into code. The first render matches the server output and animation is enabled after mount.

Which languages are supported?

language recognizes tsx, jsx, ts, js, python (py), bash (sh, shell, zsh), css (scss), json and html (xml). Any other value falls back to JavaScript-like rules that still highlight strings, comments and numbers.

How do I change the highlight colors?

Token colors live in the TOKEN_CLASS object in the source; each entry is a set of Tailwind classes including dark: variants, so edit them there. Override the frame and background with className.

What does the copy button copy?

It copies code with trailing newlines removed. On success the icon switches to a check mark and reverts after 2 seconds. If the browser blocks clipboard access (for example outside HTTPS), the component skips silently without throwing.

What are the dependencies?

motion, lucide-react, clsx and tailwind-merge; highlighting itself needs no extra package. If you prefer not to use the CLI, copy the source from the Manual tab in Installation.