Authoring site templates
A template is a site written for a purpose — a content tree plus the plugin/route/theme wiring that brief needs. Unlike themes and plugins (live dependencies), a template is scaffold-copied: its content becomes the author's to edit.
npx create-refrakt my-template --type template --scope @acme
Package shape
my-template/
template.json — the manifest (below)
content/ — the content tree copied into the project (fixed name)
sandboxes/ — optional sandbox program sources (fixed name)
The manifest
template.json is metadata + a site SiteConfig partial:
{
"kind": "site", // only "site" today
"name": "docs-starter",
"title": "Documentation site",
"description": "Multi-section docs with sidebar nav.",
"category": "docs",
"refrakt": ">=0.25 <0.26", // validated at install (ADR-023)
"site": {
"theme": { "package": "@refrakt-md/lumina", "presets": ["@refrakt-md/lumina/presets/niwaki"] },
"plugins": ["@refrakt-md/docs", "@refrakt-md/marketing"],
"routeRules": [{ "pattern": "**", "layout": "docs" }]
}
}
The site field is the same shape as refrakt.config.json — but it omits contentDir and sandbox.dir. Those destinations are install-derived from the framework starter and the target site key; an author can't know them (and a hard-coded path would collide under a non-default site key). The package always ships content/ (and optional sandboxes/) under those fixed names.
Two axes: framework × purpose
Installing composes three inputs:
npx create-refrakt my-site --framework svelte --template @acme/my-template
# └ adapter └ purpose (bundled name | dir | package)
--frameworkchooses the adapter (svelte/astro/next/nuxt/eleventy/html).--templatechooses the purpose. The template'ssiteconfig is framework-agnostic; the scaffolder injects the adapter wiring.
On install the template's content/ is copied into the project, its site config is merged into refrakt.config.json, and its plugins + theme.package are pinned as dependencies.
Stay theme-portable
Reference built-in layouts (default, docs, blog-article, plan) in routeRules so the template renders under any theme. A theme-specific custom layout couples the template to that theme — declare it a required pairing if you do.
Images without binaries
Reference images by logical key (asset:hero.jpg@cover) and seed the resolver in site.assets. With no base URL configured the scaffolded site renders shape-correct placeholders — zero bundled binaries. Set a base URL to light up real images; there is no separate "demo build".
Bundled sandboxes
Ship a sandboxes/ program tree and site.backgrounds entries for a runtime-bearing template (e.g. a visualizer hero). The runtime is CDN-loaded at activation — no npm install, no build dependency.