Page-level data
Page data is a persistent data channel keyed by a name, with no DOM element required. Good for counters, vote tallies, link trackers, anything page-shaped instead of element-shaped.
playhtml.createPageData(name, default) returns a channel handle:
const counter = playhtml.createPageData("my-counter", { count: 0 });
counter.setData((draft) => { draft.count += 1; });
counter.onUpdate((data) => { /* re-render */ }); The usePageData hook wraps createPageData with useState-style ergonomics and manages the channel’s lifecycle for you:
import { usePageData } from "@playhtml/react";
function VisitCounter() {
const [data, setData] = usePageData("visits", { count: 0 });
return (
<button onClick={() => setData((draft) => { draft.count += 1; })}>
{data.count} visits
</button>
);
} The vanilla channel handle exposes four methods (usePageData wraps these for you):
getData(): read the current value synchronously.setData(value | (draft) => void): write. Accepts a replacement value or a mutator function, with the same merge semantics as elementsetData; see data essentials.onUpdate(cb): subscribe to changes. Returns an unsubscribe function.destroy(): detach the channel and its observers. Call this when the channel is no longer needed (e.g. on teardown) to avoid leaking the subscription.
When you should reach for createPageData vs. element data, presence, or events: see the decision table on data essentials.
Navigation
Section titled “Navigation”Page data is room-scoped, like element data. On a single-page app, when navigation changes the room the channel resets to the new room: it reads its default until re-seeded. A channel handle you hold across the navigation stays usable (it keeps writing and notifying). Navigation that doesn’t change the room leaves the data untouched. See Navigation & SPAs.