Add a static asset
Add a graphic — an icon, a divider, a photo, a font — to a section.
Add a graphic — an icon, a divider mark, a photo, a custom font — to a section.
Prerequisites
Section titled “Prerequisites”- A section to hold the graphic — Install scaffolds one, with
Renderer.tsxalongsidesection.tsandfixtures.ts. - A folder inside it for the file —
assets/for a binary,components/for an inlined SVG — Organize a section’s files adds one.
A binary asset — an image, a font, a video, an archive — may live in a section’s own
sections/<section>/assets/ folder, but only if 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. An unreferenced binary in the folder is flagged; see
bundle-binary-asset for the rule and why.
A file shared across sections — a logo, a brand webfont, a texture — lives at the
template level instead, referenced the same way with a ../../assets/… path. See
Static assets for both paths and the full reference contract. What you
reach for depends on what the graphic is:
A vector graphic — an icon, a divider, a decorative mark used only here. Inline it as SVG markup directly in the JSX that draws it. It is text, ships with the rest of your component, and needs no file or import at all:
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> );}Import it into the renderer — import { ScrollArrow } from "./components/ScrollArrow";,
beside the imports that file already carries — then render it:
<ScrollArrow />That markup’s bytes ship inside the section’s renderer bundle, so they count
toward the same byte budget as the rest of your JSX — see the size stage in
Run check.
A raster image or watermark used only in this section. Add it under
sections/<section>/assets/ and import it into the component:
import crest from "./assets/crest.svg";
export default function Renderer() { return <img src={crest} alt="" className="h-8 w-auto" />;}Or reference it from the section’s CSS with url() instead of importing it — see
Static assets for both forms. Either way the file must be referenced:
an asset nothing imports or url()-references is flagged by
bundle-binary-asset.
A photo. Not a section asset at all — a section never ships a photo file. A
photo arrives at runtime through an image slot: declare it with image() in
section.ts, fill it with imageAssign() as that slot’s own fill:, and
render it through Slot.Image, which owns the marker and reads
url, alt, responsive and mobile off the binding. (The bare Image primitive is
for the other direction — a template asset, which has no slot to bind to.) See
Crop an image slot for the full shape.
A document — a brochure, a disclosure pack. Also not a section asset, and for the same
reason: it belongs to the property rather than to the template. Declare a document slot
and render it with Slot.Document — see
Document slots. A .pdf in a section’s
assets/ folder is only ever a file the template itself ships on every deliverable.
A custom font shared across the template. Declared once, for the whole
template, as a fonts entry in the theme, with the font files themselves in the
template’s own fonts/ folder — see
Loading a web font, the route a
rendered template has no alternative to. A font only one section uses can instead
live in that section’s assets/ folder and be declared with a @font-face in
the section’s own CSS — see Static assets.
Complete diff
Section titled “Complete diff”The fences under Steps are the whole change: SVG markup inlined in a
component, plus the import that pulls that component into Renderer.tsx and the
line that renders it — or a file under the section’s assets/ folder plus the import
that references it.
Verify
Section titled “Verify”Verify with the author loop.
Rules that can fire
Section titled “Rules that can fire”bundle-binary-asset— the file lands in the section folder but nothing imports orurl()-references it.size-assets— one static asset is heavier than the guideline. A warning only; it never fails the check.size-renderer-bundle— a large inlined SVG ships inside the renderer bundle and pushes it past its byte budget.
See also
Section titled “See also”- Static assets — the full reference/import contract, template level vs. section folder.
bundle-binary-asset— the rule that flags an unreferenced binary in a section folder, and the SVG-inlining fix.- Run
check— the size stage a large inlined SVG or a bloated renderer bundle counts against. - Crop an image slot — the real channel for a
photo: an
imageslot, animageAssigndecision, andSlot.Image. TokenTheme— where a template’s fonts are declared.