Static assets
Authoring static assets (svg, images, fonts) at the template level or in a section folder, and how they differ from content images.
A static asset is a file that is part of the template itself — a logo, a background texture, an icon, a brand webfont. It is authored once, is the same for every deliverable rendered from the template, and is referenced either from your CSS or from a component.
Where an asset lives
Section titled “Where an asset lives”An asset lives in one of two places:
- Template level — e.g.
templates/<template>/assets/— shared across every section in the template. Reference it from a section’s CSS with a../../assets/…path (below). - Section folder — e.g.
sections/<section>/assets/— local to that one section. A section-folder asset must be referenced: imported inRenderer.tsxorurl()-referenced from one of the section’s CSS files. An unreferenced binary in a section folder is flagged bybundle-binary-asset— it has no build meaning and can never be served.
Keep a logo, texture, or font that several sections share in the template-level folder; keep one that only a single section uses alongside that section.
Supported files
Section titled “Supported files”.svg .png .jpg .jpeg .gif .webp .avif .ico images.woff .woff2 .ttf .otf .eot fonts.mp4 .webm .mov .mp3 .wav audio / video.pdf .zip documentsReferencing an asset — from CSS with url()
Section titled “Referencing an asset — from CSS with url()”Reference a template-level asset from a section’s styles.css with url() —
a @font-face src or a background-image resolves to the asset’s built URL,
identical in the template-kit dev preview, in the editor, and on the published
page. Hand-CSS opens with a css-reason: comment (see
css-reason):
/* css-reason: brand webfont + crest watermark, both template assets */@font-face { font-family: "Brand Serif"; src: url("../../assets/fonts/brand.woff2") format("woff2"); font-display: swap;}
.hero-crest { background-image: url("../../assets/crest.svg");}The ../../assets/… path climbs out of the section folder to the template-level
assets/ directory. A font you declare here is available to the whole section.
If the family you want is one the template’s theme already loads, reference that
instead — see Theme and CSS; a font the page already has
costs nothing to reuse.
A section-folder asset is referenced the same way, with a section-relative path instead — no climbing out of the folder:
/* css-reason: hero watermark, local to this section */.hero-crest { background-image: url("./assets/crest.svg");}Referencing an asset — from a component with import
Section titled “Referencing an asset — from a component with import”An asset you render as an element — a logo, a crest — can be imported in the component and
handed to the Image primitive, whose src accepts a URL string:
import { Image } from "@homepages/template-kit";import crest from "./assets/crest.svg";
export default function Renderer() { return <Image src={crest} alt="" />;}The import resolves to the asset’s built /section-assets/… URL — the same URL in the
dev preview, the editor, and the published page. The kit ships an ambient TypeScript
declaration that types every supported asset import as that URL string, so the import
typechecks with no per-workspace setup. Use alt="" for a purely decorative
asset. (Never a raw <img> — Image carries the responsive/fallback contract; a raw
<img> is rejected by no-raw-element.)
Which to use
Section titled “Which to use”- CSS decoration (backgrounds,
@font-face, masks) →url(). - An asset rendered as an element →
import+<Image>. - A tiny glyph or icon → inline
<svg>markup — no file at all.
Assets vs. content images
Section titled “Assets vs. content images”These are two different things; keep them apart.
- A static asset is authored template decoration — a logo, a texture, a brand
font. It ships inside the template, is the same on every deliverable, and you
reference it from your CSS with
url()or by importing it into a component (above). - A content image is the property’s own content — listing photos, floor
plans, a headshot. It differs on every deliverable and flows through the
section’s slots via the
Imagedescriptor, never as a file in your template. Declare an image slot in your schema and render it with theImageprimitive; the platform supplies the actual photo per deliverable.
Rule of thumb: if the picture is the same for every home the template ever
renders, it’s an asset — place it at the template level or in the section folder
and reference it from CSS or a component import. If it changes with the
property, it’s content — give it a slot. Never hard-code a listing photo as an
asset.
Keep them lean
Section titled “Keep them lean”Every asset a section pulls in counts toward its asset budget — see
size-assets. Fonts and images are already compressed, so
the budget is raw bytes: subset a webfont to the weights and characters you use,
export images at the size they render, and drop anything a section doesn’t
actually reference.