Code Block
A syntax-highlighted code block with copy-to-clipboard, powered by shiki.
<script lang="ts">
import { CodeBlock } from "$lib/components/ui/code-block/index.js";
const code = `<script lang="ts">
let count = $state(0);
</script>
<button onclick={() => count++}>
clicks: {count}
</button>`;
</script>
<div class="flex w-full max-w-md flex-col gap-4">
<CodeBlock {code} lang="svelte" />
<CodeBlock
variant="secondary"
code="npx lily-svelte@latest add code-block"
lang="bash"
/>
</div> Installation
Install the lily base and `utils` (run once per project).
npx lily-svelte@latest init Install the `shiki` dependencies.
npm install -D shiki @shikijs/langs @shikijs/themes Copy the code-block source from the registry into $lib/components/ui/code-block.
Usage
<script lang="ts">
import { CodeBlock } from '$lib/components/ui/code-block';
const code = `console.log('Hello, lily!');`;
</script>
<CodeBlock {code} lang="ts" /> The code is highlighted client-side with shiki in both light and dark themes; until the highlighter loads (and for languages that aren't loaded), the block renders as plain text, so nothing jumps or breaks.
Languages
To keep the bundle small, only the languages listed in code-block/shiki.ts are shipped — js, ts, svelte, html, css, json, and bash by default. Add or remove entries to fit your app:
const langs = [
() => import('@shikijs/langs/typescript'),
() => import('@shikijs/langs/rust') // add any shiki grammar
]; Variants
<CodeBlock variant="secondary" code="pnpm add shiki" lang="bash" /> Props
code— the raw code to display and copy.lang— a shiki language id loaded inshiki.ts(defaults tosvelte).variant—defaultorsecondary.class— extra classes for the outer container.