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.

Preview

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.

Preview
vite.config.ts
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.

Preview
DefaultStableBetaNewDeprecated
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.

Preview
  1. 1

    Clone the repository

    Run git clone to get a local copy of the starter kit.

  2. 2

    Install dependencies

    Run pnpm install to set up all required packages.

  3. 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.

Preview
PropTypeRequiredDescription
childrenReact.ReactNodeContent rendered inside the component.
classNamestringAdditional 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.

Preview
Loading...
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

PropTypeRequiredDescription
childrenReact.ReactNodeContent rendered only after the component mounts on the client.
fallbackReact.ReactNodeContent shown on the server and during hydration. Defaults to null.