Skip to content

Code Block

Shiki wired to the phosphor palette, with a copy button. Takes a string of code and highlights it on the server.

pulls inlucide-reactshiki@afterglow/theme@afterglow/use-copied
import { Led } from "@/components/led";

export function Relay({ name, ok }: { name: string; ok: boolean }) {
  // The light is the status. There is no second copy of it in text.
  return (
    <p className="flex items-center gap-2 font-mono text-xs">
      <Led tone={ok ? "ok" : "error"} />
      {name}
    </p>
  );
}

Installation

npx shadcn@latest add @afterglow/code-block

Composition

Component structure.

CodeBlock
  • CodeBlockTitle
  • CodeBlockBody
    • CodeBlockCopy

With a title

A title puts the file name above the code and names the copy button after it.

components.json
{
  "registries": {
    "@afterglow": "https://afterglow.thebuilder.dk/r/{name}.json"
  }
}

Languages

The highlighter loads five grammars up front, and the theme maps all of them onto the phosphor tokens. A shell command and a stylesheet come out of the same palette.

install
npx shadcn@latest add @afterglow/code-block
log.css
.log {
  font-family: var(--font-mono);
  color: var(--phosphor-dim);
}

API Reference

The highlighter runs on the server, so CodeBlock is an async component and Shiki never reaches the browser. Only the copy button ships as client code.

Shiki writes the theme's CSS variables onto the tokens instead of hex, so a block follows whichever phosphor the page is set to.

lang takes any language Shiki bundles. Its grammar loads the first time a block asks for it.

CodeBlock

Highlights code and draws it in a bordered panel. label names the copy button for a screen reader, and defaults to the title.

PropTypeDefault
codestring-
langBundledLanguage"tsx"
titlestring-
labelstring-

CodeBlockTitle

The file name or caption above the code. CodeBlock renders one when you pass a title.

CodeBlockBody

The highlighted code and the copy button. Use it directly when you already hold Shiki's HTML, which is what a site that highlights once at build time will have.

Everything else is Shiki's API, documented there.