Advanced

When you need more

Everything here is optional. The first half is advanced control over the save lifecycle itself; the second half is separate libraries you add with their own script tags.

The clay attribute

Region reference

One attribute controls how any element takes part in saving. Keywords combine with spaces: clay="freeze no-undo".

KeywordPlain meaningTypical use
no-saveLives on the page, never written to disk. Live sync leaves your copy alone.Search boxes, connection badges, edit toolbars
no-snapshotInvisible to save and to sync. Every device keeps its own copy.Per-device panel state
freezeSaved exactly as authored; runtime changes to its contents are ignored.Clocks, tickers, computed summaries
no-trigger-autosaveSaved normally, but edits here don't trigger an autosave.High-churn text you'd rather batch
no-watchThe mutation system ignores it entirely (implies no autosave trigger, no undo).Third-party widgets that churn the DOM
no-undoChanges here aren't recorded in undo history.Live regions where undo would feel wrong
Recipes UI chrome (toolbars, badges) clay="no-save no-watch"
Live or computed text (clocks) clay="freeze"
Third-party embeds clay="no-watch"
Heavy editors, batch the saves clay="no-trigger-autosave"
Hooks into the save

Advanced save attributes

onbeforesave / onbeforesnapshot

“I want to clean an element up right before it's written to disk.”

Inline handlers that run on a copy of the element during the snapshot, so the live page never flickers. onbeforesave runs only for saves; onbeforesnapshot runs for every snapshot, including live-sync broadcasts.

<div onbeforesave="this.removeAttribute('data-temp')">…</div>
onaftersave

“Run something every time a save succeeds.”

<div onaftersave="console.log('saved at', event.detail.timestamp)">…</div>
refetch-on-save

“My stylesheet is generated on save; reload it without a flash.”

<link rel="stylesheet" href="style.css" refetch-on-save>
clay.cacheBust(el)

“Force one resource to re-download.”

Swaps a ?v= timestamp onto the element's href or src. Pairs well with onaftersave.

clay.beforeSave(fn)

“I need JavaScript-level control over the outgoing HTML.”

Registers a callback that receives the cloned document right before serialization. Strip, rewrite, or annotate anything; the live page is untouched.

clay.beforeSave(doc => doc.querySelectorAll(".draft-marker").forEach(el => el.remove()));
Separate libraries

Bring them in when the problem shows up

These aren't checkboxes; each is its own library with its own script tag and docs. They share clayjs's taste: HTML-first, no build step.

clay-ui toasts · modals · dialogs

“I need a toast or a confirm dialog and don't want to build one.”

Ready-made toasts, modals, and ask/confirm/tell dialogs. It listens to clay:save-* events automatically, so adding it upgrades your save feedback for free. If you already have a toast library, keep yours: the events are public.

<script src="https://clayjs.com/clay-ui.js"></script>
event attributes

“I want small behaviors without writing addEventListener boilerplate.”

onclickaway, onclickchildren, onrender, onmutation, onclone: HTML attributes for the events HTML forgot.

<script src="https://clayjs.com/clay-events.js"></script>
option visibility

“Show or hide parts of the page based on a state attribute.”

Declarative show/hide: an ancestor sets option:view="kanban", descendants opt in or out with option: / option-not: attributes.

<script src="https://clayjs.com/clay-options.js"></script>
DOM helpers

“closest() only searches up. I need the element near me.”

el.nearest(sel), el.val(), el.exec(), el.cycle(): small prototype helpers for DOM-first apps.

<script src="https://clayjs.com/clay-dom.js"></script>
All.js

“I miss jQuery's ergonomics, not its size.”

A chainable wrapper over querySelectorAll: All(".card").addClass("open").on("click", …). Zero dependencies, one file.

<script src="https://clayjs.com/all.js"></script>
utilities

“The small stuff: throttle, debounce, cookies, slugify.”

<script src="https://clayjs.com/clay-utils.js"></script>
hyper-morph exported

“I want the morphing engine itself.”

The content-based DOM morphing that powers live sync ships inside the sync plugin and is exported as clay.morph. Use it to update a page in place while preserving focus, inputs, and animations.

clay.Mutation exported

“One MutationObserver for the whole page, with region rules applied.”

The shared mutation hub that autosave and live sync sit on. clay.Mutation.onAnyChange(opts, cb) respects clay="no-watch" regions so your observers and clayjs's agree about what counts as a change.