Skip to main content

Fonts

Text draws nothing without a font. There is no substitution and no error: the text run is simply absent while everything else renders. This is the single most common way a Clayzo document goes wrong, so it’s worth understanding. A text run finds its typeface one of two ways: Embed fonts as assets. Put the file next to the document and declare it:
Then reference it from the text run with fontAssetId: "manrope". The uri resolves relative to the document on disk, so preview, export and packaging all find it. Things to know:
  • Use a permissively licensed face (an OFL family such as Manrope or Inter) that you can ship. A system font renders on your machine but can’t be embedded, and fails everywhere else.
  • With a variable font, fontWeight sets its weight: one file covers every weight on its weight axis, and a value outside the axis’s range is clamped to it.
  • A static font draws at its own weight. At a fontWeight of 600 and above, a face lighter than semibold is given a synthetic bold; a bold face is drawn as it is.
  • A glyph the face lacks draws as a hollow box. Stay within the face’s character set.
  • Text is kerned from the font. Complex scripts, right-to-left text and ligatures aren’t shaped: each character draws as one glyph, left to right. The text.shaping_fallback diagnostic is normal and means exactly this.
Family names still work locally, where the CLI can read installed fonts, and in the browser when you supply a loader (see below). A brand face you can’t ship is the usual reason to use one.

Images

An image node references the asset by id and fits it into a box. PNG, JPEG and WebP are supported. Declare the real pixel dimensions; the node’s size decides how it’s fitted.

In the browser

By default a player fetches each asset’s uri as a URL relative to the page. When that isn’t right, pass loaders:
Each loader returns the file’s bytes as a Uint8Array, or null when it has nothing. familyFontLoader is how a family-name run gets a typeface in the browser; return your best match rather than null, because null means no text. The CanvasKit player reports what it couldn’t resolve:
Wire this up in development. It is the only signal you get.

Make it portable

A .clayzo bundle embeds the document with every font, image and audio file it uses, so no loader configuration is needed anywhere:
Packaging refuses to build a bundle whose text would render as nothing, which makes it the cheapest place to catch a missing font. See Bundles.