theme-invalid
"A template's theme.ts is missing, does not export `theme`, or exports one that is not a valid TokenTheme."
Venue: check — A template’s theme.ts is missing, does not export
theme, or exports one that is not a valid TokenTheme.
Every template folder (templates/<key>/) must have a theme.ts at its root, and that
file must:
- exist — a template with no
theme.tsat all reports this once, naming the missing file; - build — the file is compiled and evaluated, so a syntax error or an unresolvable import reports here;
- export the reserved binding
theme— the name is part of the contract, exactly asschemais insection.tsandfixturesis infixtures.ts. A differently named export is not found, however well-formed the object behind it is; - export a valid
TokenTheme— the object is parsed withTokenThemeSchema, and every failing path is reported together.
This holds for every output class. A website template and a rendered-class one declare their tokens the same way and are graded the same way.
Reason
Section titled “Reason”theme.ts is a reserved contract file, and everything downstream reads it by that
contract: the CLI compiles theme.css from it, the dev server builds the preview
stylesheet from it, and the publisher builds the shipped bundle from it. A binding under
any other name is simply not there as far as those consumers are concerned.
The name only looks optional. Nothing about a website template forces the file to be read while you are authoring it — its stylesheet is assembled from the sections — so a renamed export sits there working, gets copied into the next template, and fails the first time that copy is a rendered class, as a stylesheet that would not compile. That error names CSS, and the fault is a name. Grading the file the same way for every output class is what keeps the reserved binding one contract instead of two.
Read the message: it names the template and which half of the contract failed. A renamed
export is a rename back to theme; if the old name reads better at an import site, alias
it there instead.
Before
Section titled “Before”import type { TokenTheme } from "@homepages/template-kit";
export const acmeModernTheme: TokenTheme = { colors: { ink: "#111418", page: "#ffffff" }, fonts: { sans: '"Inter", system-ui, sans-serif' }, type: { base: "1rem" }, radii: {}, shadows: {}, layout: {}, document: { font: "sans", color: "ink", background: "page", fontSize: "base" },};templates/acme-modern/theme.ts does not export `theme`. It must `export const theme: TokenTheme = { … }`.import type { TokenTheme } from "@homepages/template-kit";
export const theme: TokenTheme = { colors: { ink: "#111418", page: "#ffffff" }, fonts: { sans: '"Inter", system-ui, sans-serif' }, type: { base: "1rem" }, radii: {}, shadows: {}, layout: {}, document: { font: "sans", color: "ink", background: "page", fontSize: "base" },};An importer that wants the longer name says so at the import, where the ambiguity it is solving actually exists:
import { theme as acmeModernTheme } from "./templates/acme-modern/theme";See also
Section titled “See also”- Tokens in
TokenTheme— what the object declares, and thetheme.csscompiled from it. template-kit theme— the command that compiles it, and the exit codes for the same three failures.template-invalid— the sibling gate on the template folder’s other contract file,template.ts.