components
Components
The starter kit ships with a small set of composable components for building polished documentation pages. All components are plain React with Tailwind CSS — no component library dependencies required.
Callout
Use callouts to highlight important information, warnings, or tips to the reader.
Info: This is an informational callout. Use it for helpful context.
Warning: Pay attention to this before proceeding.
Danger: This action is destructive and cannot be undone.
function Callout({ type = 'info', children }: { type?: 'info' | 'warning' | 'danger'; children: React.ReactNode }) {
const styles = {
info: 'bg-blue-50 border-blue-200 text-blue-900',
warning: 'bg-amber-50 border-amber-200 text-amber-900',
danger: 'bg-red-50 border-red-200 text-red-900',
}
return (
<div className={`p-4 rounded-xl border text-sm ${styles[type]}`}>
{children}
</div>
)
}CodeBlock
Syntax-highlighted code blocks with a filename label and language badge.
import { defineConfig } from 'vite'
import vike from 'vike/plugin'
export default defineConfig({
plugins: [vike({ prerender: true })],
})function CodeBlock({ code, lang = 'ts', filename }: { code: string; lang?: string; filename?: string }) {
return (
<div className="rounded-xl bg-gray-900 border border-gray-800 overflow-hidden">
{filename && (
<div className="px-4 py-2 border-b border-gray-800">
<span className="text-xs text-gray-300 font-mono">{filename}</span>
</div>
)}
<pre className="p-4 overflow-x-auto text-sm text-gray-100 font-mono">
<code>{code}</code>
</pre>
</div>
)
}Badge
Small inline labels for status indicators, version tags, or category labels.
function Badge({ label, variant = 'default' }: { label: string; variant?: 'default' | 'success' | 'warning' | 'new' }) {
const styles = {
default: 'bg-gray-100 text-gray-600',
success: 'bg-green-100 text-green-700',
warning: 'bg-amber-100 text-amber-700',
new: 'bg-indigo-100 text-indigo-700',
}
return (
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${styles[variant]}`}>
{label}
</span>
)
}Step list
Numbered steps for sequential instructions, tutorials, and setup guides.
- 1
Clone the repository
Run git clone to get a local copy of the starter kit.
- 2
Install dependencies
Run pnpm install to set up all required packages.
- 3
Start the dev server
Run pnpm dev and open localhost:3000 in your browser.
function Steps({ children }: { children: React.ReactNode }) {
return <ol className="space-y-6">{children}</ol>
}
function Step({ number, title, children }: { number: number; title: string; children: React.ReactNode }) {
return (
<li className="flex gap-4">
<div className="shrink-0 w-7 h-7 rounded-full bg-indigo-600 text-white flex items-center justify-center text-xs font-bold">
{number}
</div>
<div>
<p className="font-semibold text-gray-900 mb-1">{title}</p>
{children}
</div>
</li>
)
}Props table
Document component props or function parameters in a structured table.
| Prop | Type | Required | Description |
|---|---|---|---|
| children | React.ReactNode | ✓ | Content rendered inside the component. |
| className | string | — | Additional CSS classes to merge. |
| variant | 'default' | 'ghost' | — | Visual style variant. |
function PropsTable({ rows }: { rows: { name: string; type: string; required: boolean; description: string }[] }) {
return (
<div className="rounded-xl border border-gray-200 overflow-hidden">
<table className="w-full text-sm">
<thead>
<tr className="bg-gray-50 border-b border-gray-200">
<th className="text-left px-4 py-2.5 font-semibold text-gray-700">Prop</th>
<th className="text-left px-4 py-2.5 font-semibold text-gray-700">Type</th>
<th className="text-left px-4 py-2.5 font-semibold text-gray-700">Required</th>
<th className="text-left px-4 py-2.5 font-semibold text-gray-700">Description</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-100">
{rows.map(row => (
<tr key={row.name}>
<td className="px-4 py-2.5 font-mono text-indigo-600">{row.name}</td>
<td className="px-4 py-2.5 font-mono text-xs text-gray-500">{row.type}</td>
<td className="px-4 py-2.5 text-xs">{row.required ? '✓' : '—'}</td>
<td className="px-4 py-2.5 text-gray-600">{row.description}</td>
</tr>
))}
</tbody>
</table>
</div>
)
}ClientOnly
Render children only after hydration to avoid SSR/hydration mismatches for browser-only content.
import { ClientOnly } from '../components/ClientOnly'
// Renders fallback on the server and during hydration,
// then swaps in children once the component mounts on the client.
<ClientOnly fallback={<span className="text-gray-400 text-sm">Loading...</span>}>
<span className="text-sm font-medium text-green-700 bg-green-50 px-3 py-1.5 rounded-xl border border-green-200">
Loaded on client
</span>
</ClientOnly>Props
| Prop | Type | Required | Description |
|---|---|---|---|
| children | React.ReactNode | ✓ | Content rendered only after the component mounts on the client. |
| fallback | React.ReactNode | — | Content shown on the server and during hydration. Defaults to null. |