Templates overview
How the Lithium storefront template engine works — planes, pipelines, and the two authoring workflows.
Every Feeef shop ({slug}.feeef.store) is rendered by Lithium, a Next.js storefront that
reads a JSON document called TemplateData describing the whole theme: pages, sections, and
component instances — including fully custom React components stored as code strings and
evaluated safely at runtime.
That means a theme is data, not a deployment. Developers ship themes without hosting anything; merchants install and customize them in the visual editor without touching code.
The planes
| Plane | Artefact | Role |
|---|---|---|
| Schema | Component catalog (TemplateSchema) | Declares built-in component types and what is editable (propsSchema) |
| Data | TemplateData on the store | The merchant's actual tree: pages → sections → component instances |
| Editor | Merchant app (Flutter) | Mutates data visually; renders inspectors from propsSchema |
| Renderer | Lithium (Next.js) | Maps type → React; runs custom code via react-live (server-precompiled) |
| Authoring kit | Template package on your disk | Real .tsx files compiled to data.json by the CLI |
Keep schema and data separate in your head: schema changes the catalog, data changes instances.
Render pipeline
fetchStore()
→ getTemplate(store) // draft-preview cookie → draft blob, else live templateData
→ materialize references // type:"reference" → resolved custom nodes
→ page maps sections → renderComponent()
├─ grid | flex | container → layout, recursive children[]
├─ custom → CustomLive (react-live) with injected scope
└─ anything else → built-in registry componentCustom component code is precompiled server-side per route (compiledCode), so shoppers
never run a transpiler in the browser.
Two authoring workflows
| Who | Workflow |
|---|---|
| Merchant | Visual editor in the merchant app → saves templateData directly on the store |
| Developer | Template kit: folder of .tsx files → feeef template build → draft preview on a real shop → publish to the marketplace |
The two meet in the middle: a published template becomes the merchant's starting point, and
everything you author stays editable in their visual editor because propsSchema drives the
inspector UI.
Standard pages
| Page id | Route | Notes |
|---|---|---|
home | / | Sections: header, hero, main, footer |
products | /products | Collection / PLP — see the filterator for queries |
product | /products/:slug (and /p/:slug) | Single main section; layout via slots |
checkout | /checkout | Single main section |
thank_you | /thanks | Single main section |
contact, embed, landing_page | — | Additional surfaces |
Theming
- Template root
props.theme(mode:light/dark/system) andprops.corners. - Store brand colors live in
store.decoration; Lithium converts them into CSS variables (--primary,--corners-card, …) with dark variants under.dark. - Custom components must style with
hsl(var(--primary))-style tokens — never raw decoration values — so one component works across every store and both color modes.
Dive in
Data model
The TemplateData contract: components, propsSchema, slots vs children.
Custom components
Author React components with the injected scope API — cart, store, i18n, routing.
Template kit
Folder layout, build pipeline, TypeScript + npm imports.
Marketplace
Releases, paid listings, licenses, reviews and the install API.
Order forms
COD forms: slots, drafts, geo, floating CTA, /api/orders/create.
Shared vs library
Kit $ref vs runtime reference / refId.
Theming & i18n
Dark/light tokens, corners, locales and t().
Product lists
Filterator PLP recipes for related, search and price grids.
AI in templates
Generate/edit components, landing-page jobs, the kit agent pack.