Relationships
Branches 1
History 1
3091366Created (proposed)
Context
Site templates (SPEC-109) ship purpose-built example content, and that content needs images — heroes, avatars, logos, thumbnails. Two requirements pull against each other:
- A downloaded template must carry no binary assets. Shipping real images means package weight, asset-licensing exposure, and a site that looks broken the moment the author deletes the bundled files. The author should get something that renders cleanly with zero extra files.
- A published preview of the same template should be able to show real, designed imagery. A template author (first- or third-party) will want a live demo that looks finished, not one full of grey placeholder boxes.
The same content has to satisfy both. The existing placeholder: image scheme (packages/runes/src/lib/placeholder.ts) renders deterministic, token-tinted SVGs and solves the no-asset case — but it is keyed by shape (placeholder:cover, placeholder:avatar), so it cannot distinguish two different heroes or map a specific image slot to a specific preview image. We need a way to reference an image slot by stable identity and resolve it differently depending on build mode.
The enabling fact: the image-scheme registry is already pluggable and last-registration-wins — registerImageScheme(scheme, resolver) in packages/runes/src/lib/image-schemes.ts. A build can swap a resolver wholesale without touching content.
Sub-question: how does shape travel with the ref?
For a downloaded site to render a shape-correct placeholder with no manifest present, the slot's aspect must be derivable from the content alone. Two candidate ref syntaxes:
- A. Self-describing ref —
asset:<shape>/<key>(e.g.asset:cover/hero-main). Shape is in the ref, so a downloaded site needs zero extra files; the manifest only addspreviewUrls, consumed solely in demo mode. - B. Key-only ref —
asset:<key>, with shape looked up from a manifest copied into the scaffolded project.
Leaning toward A (self-describing): it best satisfies SPEC-109's "downloaded site needs no extra files" goal and keeps distributed-mode resolution a pure function of the content. B is left open only if a compelling reason to centralize per-key metadata emerges. Final syntax is settled in the SPEC-109 work phase.
Decision
Adopt Option 3: a logical asset: image scheme with dual-mode resolution over identical content — generated placeholders when distributed, author-provided previewUrls under an opt-in demo-build mode — implemented via the existing last-wins resolver registry. The ref is expected to be self-describing for shape (candidate A), with exact syntax finalized during implementation.
Rationale
The two requirements (no binary assets in downloads; real imagery in previews) are irreconcilable with a single static asset set, but trivially reconciled by making resolution mode-dependent while keeping content fixed. The registry already supports exactly this with no new core mechanism, so the cost is one scheme plus a flag. Keeping previewUrls out of the scaffolded output means the no-asset and no-licensing-exposure guarantees hold by construction, not by a cleanup step that could be skipped.
Critically, how preview images are produced and hosted is entirely out of scope — the manifest holds author-provided URLs and nothing about their origin. The repository gains a neutral capability useful to any template author; it encodes no assumption about a particular preview pipeline or distribution channel.
Consequences
- A new core image scheme
asset:is registered alongsideicon:andplaceholder:; distributed builds resolve it to generated placeholders, so behaviour for existing content is unchanged. - A build-mode flag (env or config) registers the demo-mode override resolver. It is inert for normal site builds.
template.jsongains an asset manifest (key → { shape?, previewUrl, alt? }); onlypreviewUrl/altare demo-only, and they are never written into a scaffolded project.- Template content authoring uses
asset:for imagery that should be swappable, reserving bareplaceholder:for purely decorative shape fills where identity does not matter. - The exact
asset:ref syntax (self-describing vs. key-only) is the one open detail, resolved in the SPEC-109 work phase against the "zero extra files in a download" test.
References
- Site templates spec: SPEC-109.
- Image-scheme registry:
packages/runes/src/lib/image-schemes.ts(registerImageScheme,resolveImageScheme, last-registration-wins). - Placeholder generator + shapes:
packages/runes/src/lib/placeholder.ts(placeholderSvg,PLACEHOLDER_SHAPES).