Examples
Interactive demos powered by talkDOM. Each example runs live on this page.
Basic GET + Apply
Click the button to fetch content from a partial and insert it into the receiver.
View Source
<div receiver="demo1">Content will appear here...</div> <button sender="demo1 get: /partials/demos/hello.html apply: inner"> Load Content </button>
Append Content
Each click appends new content without removing existing content.
View Source
<div receiver="demo2"></div> <button sender="demo2 get: /partials/demos/counter.html apply: append"> Append Entry </button>
Pipe Chaining
Fetch content with get: then pipe the result to apply: in a separate step.
View Source
<div receiver="demo3">Waiting for piped content...</div> <button sender="demo3 get: /partials/demos/hello.html | demo3 apply: inner"> Fetch & Apply via Pipe </button>
Parallel Chains with Semicolons
Update two receivers simultaneously with independent chains separated by ;
View Source
<div receiver="demo4a">Empty</div>
<div receiver="demo4b">Empty</div>
<button sender="demo4a get: /partials/demos/hello.html apply: inner;
demo4b get: /partials/demos/counter.html apply: inner">
Load Both
</button>
Custom Methods
Register a custom toggle: method and use it in sender attributes.
View Source
<script>
talkDOM.methods["toggle:"] = function(el, cls) {
el.classList.toggle(cls);
};
</script>
<div receiver="demo5">
This box will toggle its background color.
</div>
<button sender="demo5 toggle: bg-amber-400/20">
Toggle Background
</button>
Loading State
This site registers a custom get:apply:loading: method to toggle a CSS class on the receiver during async operations.
View Source
talkDOM.methods["get:apply:loading:"] = function(el, url, op, cls) {
el.classList.add(cls);
return talkDOM.methods["get:apply:"](el, url, op)
.finally(function() { el.classList.remove(cls); });
};
<style>.is-loading { opacity: 0.5; }</style>
<div receiver="demo6a">This box dims while loading.</div>
<button sender="demo6a get: /partials/demos/hello.html apply: inner loading: is-loading">
Load with Indicator
</button>
Confirm Before Action
Use confirm: to gate an action. Cancel aborts the chain.
View Source
<div receiver="demo7"> Click the button and confirm to replace this content. </div> <button sender="demo7 confirm: Replace content? | demo7 get: /partials/demos/hello.html apply: inner"> Confirm & Load </button>
Programmatic API
Dispatch messages from JavaScript with talkDOM.send().
View Source
<div receiver="demo8">Waiting for programmatic send...</div>
<button onclick="talkDOM.send('demo8 get: /partials/demos/hello.html apply: inner')">
talkDOM.send()
</button>
Safe Text Output
Use text: to write a literal value. The receiver only accepts text updates.
View Source
<div receiver="notice" accepts="text">Ready</div> <button sender="notice text: Saved successfully">Save</button>
Persist a Small Preference
The persist attribute saves successful updates in same-origin local storage. Choose a value, then refresh this page.
View Source
<div receiver="preference" accepts="text" persist>Choose a theme</div> <button sender="preference text: Preference saved as dark">Dark</button>
Replace the Receiver Element
Unlike inner, outer replaces the receiver itself. The response keeps the same receiver name so it can be targeted again.
View Source
<div receiver="card" accepts="outer">Original card</div> <button sender="card get: /card.html apply: outer">Replace</button> <!-- /card.html must return a replacement with receiver="card" --> <div receiver="card" accepts="outer">New card</div>
Tips & Tricks
A few habits that make message-driven pages easier to maintain.
Choose the apply operation deliberately
inner replaces a receiver’s contents, append adds to a list, text writes literal text, and outer swaps the receiver element.
Use unique receiver names
A message updates every element with that receiver name. Reuse a name when you want coordinated updates; otherwise give each target its own name.
Use pipes for dependencies
A pipe passes one result to the next step. Separate independent work with a semicolon so both chains can start together.
Persist only non-sensitive UI state
Persisted markup is stored as plain text in same-origin local storage. Never put tokens, passwords, or private data there.
Delegate events for changing content
Listen on a stable ancestor such as document when controls may be replaced. talkDOM also bubbles talkdom:done and talkdom:error events.
Keep form bodies explicit
Core post: sends a request without serializing a form. Register a custom method for validated form or JSON payloads.
For arbitrary values, pass arguments directly instead of building a message string:
const notice = document.querySelector('[receiver="notice"]');
await talkDOM.deliver(notice, "text:", [userProvidedValue]);