With Filename
A header bar names the source file and holds the copy button.
<CodeBlock filename="app.tsx" code={`import { Button, Card } from '@usefragments/ui';
function App() {
return (
<Card>
<Card.Header>Welcome</Card.Header>Shows code with syntax colors, a copy button, and diff or collapse when you need them.
import { CodeBlock } from "@/fragments/ui";Source<CodeBlock code={`import { Button } from '@usefragments/ui';
function App() {
return <Button>Click me</Button>;
}`} language="tsx" />npx @usefragments/cli add codeblockpnpm add shikiWrites src/fragments/ui/components/CodeBlock plus what it imports, the globals stylesheet, and .fragments/registry-lock.json, then prints the packages to add. No account, no key.
Your own registry: publish from Fragments Cloud and add --registry org/name. Connect a workspace.
CodeBlock is a compound: import the root and reach its parts through dot notation.
CodeBlock.TabbedA header bar names the source file and holds the copy button.
<CodeBlock filename="app.tsx" code={`import { Button, Card } from '@usefragments/ui';
function App() {
return (
<Card>
<Card.Header>Welcome</Card.Header>A label above the block, outside the code surface.
<CodeBlock title="Installation" code="npm install @usefragments/ui" language="bash" />A footer line for the aside that does not belong in the code.
<CodeBlock
code={`const API_URL = process.env.NEXT_PUBLIC_API_URL;`}
language="typescript"
caption="Environment variables must be prefixed with NEXT_PUBLIC_ to be available in the browser."
/>Turn these on once a snippet is long enough to point at.
<CodeBlock code={`const greeting = "Hello";
const name = "World";
console.log(\`\${greeting}, \${name}!\`);`} language="typescript" showLineNumbers />Numbering starts where the excerpt actually starts in the file.
<CodeBlock
code={` return (
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
);Marks the lines the prose is talking about.
<CodeBlock code={`import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (Added and removed lines, side by side with the rest.
<CodeBlock
code={`import { useState } from 'react';
import { useCallback } from 'react';
function Counter() {
const [count, setCount] = useState(0);Any Shiki theme works — pass its name to theme.
<CodeBlock
code={`async function fetchUser(id: string) {
const response = await fetch(\`/api/users/\${id}\`);
return response.json();
}`}
language="typescript"Long lines break instead of scrolling sideways.
<CodeBlock
code={`const longString = "This is a very long string that would normally cause horizontal scrolling, but with word wrap enabled it will break to the next line instead.";`}
language="typescript"
wordWrap
/>Caps the height so one snippet cannot own the page.
<CodeBlock
code={`// This code block has a maximum height
function processItems(items: string[]) {
const results = [];
for (const item of items) {
if (item.startsWith('_')) {Shows the opening lines and hides the rest behind a toggle.
<CodeBlock
code={`import React, { useState, useEffect } from 'react';
interface User {
id: string;
name: string;Config files highlight the same way source does.
<CodeBlock title="package.json" code={`{
"name": "my-app",
"dependencies": {
"@usefragments/ui": "^0.3.0"
}
}`} language="json" />Drop the copy button when the snippet is not meant to be reused.
<CodeBlock code="const simple = true;" language="typescript" showCopy={false} />Prop | Type | Default | Description |
|---|---|---|---|
codeRequired | string | Not set | The code string to display |
language | enumtsxtypescripttsjavascriptjsjsxbashshellcssscsssassjsonhtmlxmlmarkdownmdyamlymlpythonpyrubygorustjavakotlinswiftccppcsharpphpsqlgraphqldiffplaintexttext | tsx | Programming language for syntax highlighting |
theme | enumcss-variablessynthwave-84github-darkgithub-lightone-dark-prodraculanordmonokaivitesse-darkvitesse-lightmin-darkmin-light | css-variables | Syntax highlighting theme. css-variables maps spans onto --fui-code-token-* so both themes stay readable. |
showCopy | boolean | true | Whether to show the copy button |
title | string | Not set | Optional title displayed above the code block (external label) |
filename | string | Not set | Optional filename shown in header bar inside code block |
caption | string | Not set | Optional caption displayed below the code block |
showLineNumbers | boolean | false | Whether to display line numbers |
startLineNumber | number | 1 | Starting line number (useful for code excerpts) |
highlightLines | array | Not set | Lines to highlight (e.g., [1, 3, "5-7"]) |
addedLines | array | Not set | Lines marked as added in diff view (e.g., [2, "4-6"]) |
removedLines | array | Not set | Lines marked as removed in diff view (e.g., [1, 3]) |
wordWrap | boolean | false | Enable word wrapping for long lines |
maxHeight | number | Not set | Maximum height in pixels (enables scrolling) |
collapsible | boolean | false | Allow collapsing/expanding the code block |
defaultCollapsed | boolean | false | Initial collapsed state (only applies when collapsible is true) |
collapsedLines | number | 5 | Number of lines to show when collapsed |
collapseAction | enumlinesexpand | lines | Collapse control copy: line-count bar, or a single Expand / Collapse control |
compact | boolean | false | Compact mode with reduced padding |
persistentCopy | boolean | false | Show a persistent copy button that is always visible |
copyPlacement | enumautoheaderoverlay | auto | Where to place the copy button when not using persistentCopy |
bg | string | Not set | Custom background color for the code block (useful when the content area is pure black or dark gray) |
onCopy | function | Not set | Callback fired when the copy button is clicked and copy succeeds |