Skip to content
HomePagesHomePages template kit
Menu

template-kit/bundle-binary-asset

The template-kit/bundle-binary-asset authoring rule — what it enforces, why, and how to fix it.

A static asset may live in a section folder — but only if something references it. An unreferenced binary is dead weight and can never be served.

A binary asset inside a section folder is allowed only when the section references it — imported in Renderer.tsx (import crest from "./assets/crest.svg") or url()-referenced from one of the section’s CSS files. A binary that nothing references is flagged. The check looks two ways to find candidates:

  • By extension.svg, .png, .jpg/.jpeg, .gif, .webp, .avif, .ico, .woff/.woff2, .ttf, .otf, .eot, .mp4, .webm, .mov, .mp3, .wav, .pdf, .zip.
  • By content — any other file whose first bytes contain a NUL byte.

A referenced asset is first-class: the build content-hashes it to a stable /section-assets/ URL and the publish pipeline uploads it — identical in the dev preview, the editor, and the published page. An unreferenced binary has no such URL: it is never emitted or uploaded, yet it still counts toward the section’s content hash (its identity). So it is pure dead weight — a file that ships nowhere.

Either reference the asset, or delete it.

  • Reference it from a component: import crest from "./assets/crest.svg" and render it with the Image primitive — <Image src={crest} alt="…" />. See Static assets.
  • Reference it from CSS: background-image: url("./assets/crest.svg") (or a @font-face src) in the section’s styles.css.
  • Delete it if it is left over and unused.
sections/hero/
Renderer.tsx
schema.ts
fill-spec.ts
fixtures.ts
assets/
crest.svg ← nothing imports or url()-references this file
sections/hero/Renderer.tsx
import { Image } from "@homepages/template-kit";
import crest from "./assets/crest.svg";
export default function Renderer() {
return <Image src={crest} alt="" />;
}

For a tiny glyph or divider, prefer inline <svg> markup over a file at all — it ships with your JSX, needs no asset at all, and costs no extra request:

export function ScrollArrow() {
return (
<svg viewBox="0 0 16 16" className="h-4 w-4" fill="none" aria-hidden="true">
<path d="M8 3v10M3 9l5 4 5-4" stroke="currentColor" strokeWidth="1.5" />
</svg>
);
}