Glossary

Mirror pipeline

ng.state runs two pipelines: mirror — two-way sync between a form control and the app state — and dataset snapshot — a one-shot, write-only capture on event. The attribute that separates them is data-state-from.

Both pipelines persist into localStorage (ng:appState), support per-key/namespace/global TTL with automatic purge at load, sync across tabs via BroadcastChannel, and notify watchers plus a global ng:state:change event. Never write to the internal app state directly — always go through ng.state.set.

Mirror — two-way

An input marked data-ng-state with data-state-from stays in sync in both directions: typing/toggling updates the state, and a programmatic ng.state.set() updates the DOM.

mirror.html
<input type="checkbox"
       data-ng-state
       data-state-id="prefs:newsletter"
       data-state-from="checked">

<!-- DOM change → appState updated; ng.state.set() → DOM updated -->

Mirror attributes

data-ng-stateMarks the element as state-aware.
data-state-idState key — recommended format namespace:prop.
data-state-fromValue source: value or checked. Its presence selects the mirror pipeline.
data-state-defaultDefault when both DOM and storage are empty.
data-state-ttlExpiry in seconds.
data-state-debounceDebounce in ms for text inputs (default 300).

Dataset snapshot — write-only

The same marker without data-state-from: the value is captured once, on event (a click on a button, a commit on an input). Nothing flows back to the DOM.

snapshot.html
<button type="button" class="ng-btn ng-btn-primary"
        data-ng-state
        data-state-id="wizard:step"
        data-state-val="2">
    Continue
</button>

<!-- one-shot: clicking writes "2" into wizard:step. Write-only. -->

Snapshot attributes

data-state-valStatic value to store (buttons, links).
data-state-getDynamic source: value, checked or attr.
data-state-defaultFallback when the captured value is empty.

Choosing one

MirrorThe value must stay in sync: settings toggles, filters, live form state restored across reloads and tabs.
SnapshotYou only need to record a value at a moment: wizard step reached, last chosen tab, a tracking flag.

Runtime API

app.js
ng.state.get('prefs:newsletter');          // read (null if expired)
ng.state.set('prefs:newsletter', true);    // write — mirrored inputs update too
ng.state.watch('prefs:newsletter', v => console.log('changed:', v));
ng.state.setTTL('prefs', 3600);            // TTL: key > namespace > '*'

document.addEventListener('ng:state:change', e => {
    console.log(e.detail.key, e.detail.value, e.detail.source);
});

Related

ng.state.get ng.state.set ng.state.watch ng.state.unwatch ng.state.setTTL ng:state:change BroadcastChannel

Live demos on the State component page.