MODULE ELEMENTS — elements that use a store MODULE (reservations, …). A module installed on the store ships three things into the element library: its OWN elements (origin: {module, version} on the doc), ONE shared css and script — the module RUNTIME, the element {moduleId}_runtime (its css = the kits' global.css, its js = global.js, exposing a global such as DropReservations) — and, unless it is an ELEMENTS module (hosting: "none" in listStoreModules — a library with no backend), backend routes under /m/{moduleId}/*. The renderer loads the runtime ONCE per page — its css BEFORE the element css, its script after the shared element runtime and BEFORE the element scripts — on exactly the pages that place an element whose doc names the module.
BEFORE building or editing one: listStoreModules (what is installed and enabled, each module's elements and their state) → readModuleGuide(moduleId) (the runtime API, routes with shapes, data attributes, events, translation keys, CSS hooks, an example element). Never guess a runtime's API, and never build on a module that is not installed or is disabled — its elements do not render.
RULES:
- SET
moduleon EVERY element that uses a module (writeStoreElementmodule). Without it the page never loads the runtime's shared css and script and the element renders dead and unstyled; with it the element is also hidden while the module is disabled or uninstalled. A module's own elements already carry it. - CALL THE RUNTIME, never the backend:
Drop{Name}.book(…),.availability(…),.mount(kind, root)— whatever the guide documents. Never raw-fetcha/m/{moduleId}/*path: the guarded ones need the form-guard token and timing the runtime owns, and a hand-rolled call breaks on the next module update. The element'sjsshrinks to wiring: query its data attribute, guard with a…-readystamp, call the runtime'sinit/mount. - VISITOR-FACING TEXT comes from the module's translation group —
{{t "…"}}with the keys the guide lists. Do not hardcode strings and do not invent keys; add your own keys to your own group only for text the module does not cover. - VALUES THE RUNTIME RETURNS ARE DATA, NEVER MARKUP: names, notes, error messages and slot labels arrive from visitors and from a third-party backend. Write them with
textContentor DOM building (createElement,append) — neverinnerHTML/insertAdjacentHTML/outerHTML. The write tools warn when a module element'sjsuses one. - NEVER EMBED a module element: its placement stays LIVE (
{type:"element", element, data}, noembedded:true). An embedded copy freezes the code inside a page template, outside the runtime include and the module's updates. - NEVER TOUCH THE RUNTIME:
{moduleId}_runtimeis module-controlled, overwritten on every update, and its writes and deletes are refused. Never copy its shared css or script into an element or intosetup/elementscss / js either — change behavior in your own element, through the runtime's API, and override the module's look in your own element's css (it loads after the module's global css).
EDITING A MODULE'S OWN ELEMENT is allowed, with one consequence: once its fields/html/css/js differ from what the module shipped it is CUSTOMIZED — module updates skip it (it stays as edited, at the version it was based on) until a human resets it on the module page. So choose deliberately:
- A TWEAK (spacing, a class, one extra field) → edit it in place, and say in your summary that the element is now customized and no longer follows module updates.
- A DIFFERENT DESIGN or a second variant → leave the module's element pristine: duplicate it (writeStoreElement
forkOfwith a new elementId — copies the source and stampsmodule+forked; in the console, Duplicate) or build a new element withmoduleset, then place that one. A module's own elements cannot be deleted while the module is installed; uninstalling removes them, while duplicated and newly built elements stay in the library but stop rendering.