ID:SPEC-007Status:draft
Branches 3
claude/align-sidenav-styling-4MuxV current draft
claude/file-naming-convention-LJdwR draftmain draftchangeset-release/main draft Context
Projects need custom interactive components in content — a playground, a pricing calculator, a product demo. Rather than a {% component %} escape hatch that breaks out of the rune system, local runes extend it. To the content author, a local rune looks identical to a built-in rune. The only difference is where it's defined.
This spec covers v1 runtime support: config declaration, schema generation, content parsing, and component rendering. VS Code language server support is a fast-follow.
v1 Config Surface
Local runes are declared in refrakt.config.json:
{ "contentDir": "./content", "theme": "@refrakt-md/lumina", "target": "svelte", "runes": { "playground": { "component": "./src/components/Playground.svelte", "description": "Interactive code playground with live preview", "attributes": { "height": { "type": "number", "default": 600 }, "example": { "type": "string", "default": "default" }, "editable": { "type": "boolean", "default": true } }, "children": "render" }, "pricing-calculator": { "component": "./src/components/PricingCalculator.svelte", "description": "Interactive pricing calculator", "attributes": { "currency": { "type": "string", "default": "USD" }, "plans": { "type": "string" } } } } }
Config Fields
| Field | Type | Required | Default | Purpose |
|---|---|---|---|---|
component | string | Yes | — | Path to Svelte component (relative to project root) |
description | string | No | "" | Human-readable description (used by language server in fast-follow) |
attributes | Record<string, AttrDef> | No | {} | Attribute schema for validation |
children | "none" | "render" | No | "none" | How children are handled |
Attribute Definition
interface AttrDef { type: "string" | "number" | "boolean"; default?: string | number | boolean; required?: boolean; }
Children Modes
"none" (default) — Self-closing tag. No closing tag needed. Component receives only declared attributes.
{% pricing-calculator plans="starter,pro" %}