Skip to content
HomePagesHomePages template kit
Menu

template-kit/image-bare-needs-reason

The template-kit/image-bare-needs-reason authoring rule — what it enforces, why, and how to fix it.

<Image bare> needs a // bare: <reason> comment above it. A reason cannot be spent twice — one comment documents exactly one element.

Every <Image bare …> must have a qualifying reason comment. A comment qualifies when all three hold:

  1. It contains bare: — e.g. // bare: the logo is chrome; the parent already sizes it.
  2. It sits strictly above the element, within 5 lines. Above, not beside and not below.
  3. It has not already been spent on an earlier <Image bare>.

Both comment forms count — a // line comment and a {/* … */} JSX comment. The rule reads the raw comment stream rather than hopping up the AST, so proximity survives arbitrary wrapping: a container <div>, a .map() callback, a parenthesized return, an assignment to a const. If it looks directly above the element, it counts.

The surprising part: a reason cannot be spent twice. One comment above a row of sibling bare logos documents only the first of them; the second still reports. Each bare image is its own decision, so each gets its own sentence. (A comment written between two bare images is fine for the second — it starts after the first element ends.)

Framed is <Image>’s default, and the frame is load-bearing: a wrapper div that holds the aspect-ratio box, carries the slot marker, and renders a neutral fallback rect when src is empty.

bare drops all of it — one <img>, no wrapper. So a bare image with no source is nothing at all: the layout collapses, and whatever sat below it jumps up the page. A missing image is a supported state on this platform (a thin listing simply has no photo), so “the source is always there” is an assumption, not a fact.

bare is still the right call sometimes — a logo whose parent already establishes the box, a slide inside its own aspect-ratio parent. The rule does not ban it; it makes you say why the parent guarantees the box, so the next author (or the next agent) can tell whether the frame is safe to restore.

Put a // bare: <reason> comment immediately above the element. A reason is legitimate in either of two ways: it can name what guarantees the layout box without <Image>’s frame (a parent that already establishes the size, a slide inside its own aspect-ratio container) — or it can name something about the image’s own content that makes the frame the wrong choice, such as a transparent PNG that framing would letterbox. If neither holds, drop bare and let <Image> frame it.

import { Image, Section } from "@homepages/template-kit";
import type { Props } from "./schema.js";
export function Renderer({ slots }: Props) {
return (
<Section>
<div className="h-12 w-32">
<Image bare src={slots.brand_logo.url} alt={slots.brand_logo.alt} className="object-contain" />
</div>
</Section>
);
}
import { Image, Section } from "@homepages/template-kit";
import type { Props } from "./schema.js";
export function Renderer({ slots }: Props) {
return (
<Section>
<div className="h-12 w-32">
{/* bare: the logo is chrome; the parent already sizes it. */}
<Image bare src={slots.brand_logo.url} alt={slots.brand_logo.alt} className="object-contain" />
</div>
</Section>
);
}

Two bare images need two comments — the first one’s reason is spent:

<div className="flex gap-4">
{/* bare: the primary logo is chrome; the row sizes it. */}
<Image bare src={slots.logo_a.url} alt={slots.logo_a.alt} className="h-8 object-contain" />
{/* bare: the partner logo is chrome; the row sizes it. */}
<Image bare src={slots.logo_b.url} alt={slots.logo_b.alt} className="h-8 object-contain" />
</div>

A content-based reason is written the same way — only the sentence changes, because it’s justifying a different thing (the image, not the layout around it):

{/* bare: a transparent PNG badge; Image's frame would letterbox its transparent
padding against the section background. */}
<Image bare src={slots.certification_badge.url} alt={slots.certification_badge.alt} className="h-10" />