π― context: The Action ObjectΒΆ
context is the object Clera passes to every action function and lifecycle hook. It provides information about the current page and helpers for common tasks.
Think of it as your toolbox for that page. Navigation, data, DOM updates, form values, and network calls are all here.
β οΈ context is only available inside action functions and lifecycle hooks. It does not exist at the top level of your script. Accessing it outside a handler returns null and logs:
[CLERA:CONTEXT_OUTSIDE_HANDLER] context accessed outside an active handler.
context is only available inside action handlers and lifecycle hooks.
π For things you need at the global level (timeouts, intervals, event listeners), use app.* equivalents:
Need |
Inside a function |
Outside a function |
|---|---|---|
Timed callback |
|
|
Repeating callback |
|
|
DOM event listener |
|
|
Trigger DOM update |
|
|
Navigate |
|
|
πΊοΈ OverviewΒΆ
function myAction(context) {
context.pageName // name of the current page
context.params // navigation params passed to this page
context.event // the triggering DOM event (or null)
context.element // the element that triggered the action (or null)
context.navigate() // navigate to another page
context.back() // go back
// Data system
context.data() // attach page-local data
context.update() // manually patch DOM bindings
context.fetch() // Clera-aware fetch (auto-updates DOM)
context.timeout() // Clera-aware setTimeout (auto-updates DOM)
context.myDataKey // direct access to any key you attached via context.data()
context.query() // find an element in the page
context.render() // replace element content
context.append() // add to element content
context.clear() // empty an element
// form actions only:
context.values // form field values as a plain object
context.formData // raw FormData object
context.form // the HTMLFormElement
context.submitter // the button that submitted the form
context.resetForm() // reset the form
context.setSubmitting() // control the submitting lock
context.log // dev logging helpers
context.unsafe // escape hatches to raw DOM
}
π PropertiesΒΆ
π context.pageNameΒΆ
The name of the page this action is running on.
console.log(context.pageName); // "home"
π¦ context.paramsΒΆ
Parameters passed during navigation. Empty object if none were passed.
app.navigate("profile", { userId: 42 });
// inside the profile page:
console.log(context.params.userId); // 42
π±οΈ context.eventΒΆ
The raw DOM event that triggered the action. null for lifecycle hooks.
π² context.elementΒΆ
The element that triggered the action. For form actions, this is the submitter button (or null).
π¦ context.args and context.argΒΆ
When an action is called with inline arguments, they are available on context.args (frozen array) and context.arg (first item shorthand, null when no args were passed).
Both syntaxes land identically:
<button action="deleteTask: {task.id}">Delete</button>
<button action="deleteTask({task.id})">Delete</button>
function deleteTask(context) {
const id = context.arg; // first arg shorthand
}
function move(context) {
const id = context.args[0];
const status = context.args[1];
}
See 04 Actions for the full argument syntax, all supported types, and binding resolution rules.
ποΈ Data systemΒΆ
π₯ context.data(sourceObject)ΒΆ
Attach page-local data. Merges by reference: keys become directly accessible on context.*. Page data overrides global data of the same key on this page only.
function loadHome(context) {
const stats = { count: 0 };
context.data({ stats });
context.stats.count; // 0: direct access
}
β οΈ Avoid naming your data keys after Clera built-in properties like
navigate,render, orpageName. Clera will reject them with[CLERA:DATA_KEY_RESERVED]and skip that key.
π context.listen(selector, eventName, callback, options?) β off()ΒΆ
Attaches an event listener to elements inside the current page. The callback runs inside Cleraβs execution cycle so DOM bindings update automatically after each event. Auto-rebinds after context.render(), context.append(), and context.clear(). Prevents duplicates via callback reference identity.
const off = context.listen(".item", "click", (event) => {
context.data({ selected: event.target.textContent });
});
off(); // remove rule and all element attachments
See 15 Page Listeners for full usage.
π context.update()ΒΆ
Manually trigger a DOM binding patch. Use when data mutates outside Clera-controlled execution (raw setTimeout, raw fetch, WebSocket etc.).
setTimeout(() => {
context.stats.count += 1;
context.update(); // manual trigger required
}, 1000);
π context.fetch(url, options?, callback?) β PromiseΒΆ
Clera-aware fetch. DOM bindings update automatically after callback or await resolves. No context.update() needed.
// Callback style
context.fetch("/api/data", function(result) {
context.stats.count = result.count; // auto-updates DOM
});
// Async/await
const result = await context.fetch("/api/data", { method: "POST", body: { name } });
See 11 Async Helpers for full options reference.
β±οΈ context.timeout(callback, delay) β timerIdΒΆ
Clera-aware setTimeout. DOM bindings update automatically after the callback runs.
context.timeout(function() {
context.message.text = "Done!"; // auto-updates DOM
}, 2000);
π context.myDataKeyΒΆ
Any key attached via context.data() or app.data() is accessible directly on context:
context.data({ stats, filters });
context.stats.count; // direct access
context.filters.active; // direct access
π DOM helpersΒΆ
All DOM helpers are scoped to the current page. They cannot reach elements outside the active page.
π context.query(cssSelector)ΒΆ
Find an element within the current page. Returns a safe wrapper object.
const wrapper = context.query("#title");
wrapper.exists // true or false
wrapper.element // raw HTMLElement or null
wrapper.text("Hello") // set text content
wrapper.text() // get text content
wrapper.html("<b>Hi</b>") // set innerHTML
wrapper.value("new") // set input value
wrapper.value() // get input value
wrapper.on("click", fn) // add event listener
ποΈ context.render(selector, html, options?)ΒΆ
Replace the inner HTML of an element. Processes {path} bindings in injected HTML automatically.
context.render("#taskList", tasks.map(t => `<li>${t}</li>`).join(""));
// Prevent layout jump during swap:
context.render("#feedList", html, { reserveHeight: true });
β context.append(selector, html)ΒΆ
Add HTML to an element without clearing existing content. Processes {path} bindings in the appended fragment.
context.append("#taskList", `<li>${newTask}</li>`);
ποΈ context.clear(selector)ΒΆ
Empty an element.
context.clear("#taskList");
π Form helpers (form actions only)ΒΆ
π context.valuesΒΆ
Form field values as a plain object. Fields with the same name become arrays.
context.values.title // "Buy milk"
context.values.tags // ["design", "code"] (multiple checkboxes)
π context.formΒΆ
The raw HTMLFormElement. context.form.reset() clears the form.
π¦ context.formDataΒΆ
The raw FormData object for advanced use cases (file uploads etc.).
π±οΈ context.submitterΒΆ
The button that submitted the form, or null.
π context.resetForm()ΒΆ
Resets the form. Equivalent to context.form.reset().
π context.setSubmitting(boolean)ΒΆ
Manually control the double-submit lock.
π LoggingΒΆ
context.log emits structured entries into the Clera diagnostics buffer from your own code. Entries appear in app.diagnostics alongside runtime entries and are formatted in the console as [CRE:CODE] message.
context.log.warn("MY_CODE", "Something unexpected happened");
context.log.error("MY_CODE", "Something failed", caughtError);
Method |
Level |
When to use |
|---|---|---|
|
|
Unexpected but recoverable. Will not stop execution. |
|
|
Failed operation. Pass the caught error as the third argument to append its message. |
code should be a stable ALL_CAPS string that identifies the call site. It appears in the console and in app.diagnostics.logs() entries for filtering and tooling support.
πͺ Escape hatchesΒΆ
context.unsafe gives direct access to raw DOM objects that Cleraβs scoped helpers cannot reach. Use only when the standard helpers are not sufficient.
context.unsafe.root() // the live <page> DOM element
context.unsafe.document() // window.document
context.unsafe.window() // window
Direct DOM manipulation via context.unsafe bypasses the binding engine. Changes made this way will not trigger {path} binding updates. Call context.update() after if bindings need to reflect any changes.