Documentation

Everything you need to know about talkDOM.

Installation

Choose whichever method fits your project.

CDN

Add a single script tag. No build tools, no configuration.

<script src="https://cdn.jsdelivr.net/npm/talkdom/dist/talkdom.min.js"></script>

npm

npm install talkdom

That's it. talkDOM is ready to use.

Core Concepts

talkDOM uses two HTML attributes to wire up interactions: receiver and sender.

Receivers

A receiver attribute marks an element as a message target. The value is the receiver's name.

<div receiver="content"></div>

Senders

A sender attribute makes an element dispatch messages on click. Messages follow Smalltalk keyword syntax:

receiver keyword: arg keyword: arg

The first word is the receiver name, followed by keyword-argument pairs.

Example

Click the button to fetch /page.html and insert its content into the receiver:

<div receiver="content"></div>
<button sender="content get: /page.html apply: inner">Load</button>

Apply Operations

The apply: keyword determines how fetched content is inserted into the receiver. Four modes are available:

Mode Behavior
inner Replaces innerHTML
text Sets textContent
append Appends via insertAdjacentHTML
outer Replaces the receiver element itself via outerHTML

Restricting operations

Use the accepts attribute to restrict which operations a receiver allows:

<div receiver="output" accepts="text inner"></div>

This receiver will reject append and outer operations.

HTTP Methods

talkDOM supports four HTTP keywords. Each takes a URL and returns the response text:

get:    → GET request
post:   → POST request
put:    → PUT request
delete: → DELETE request

Combined fetch + apply

Combine an HTTP method with apply: in a single message to fetch and insert in one step:

<!-- GET and replace inner HTML -->
<button sender="feed get: /api/posts apply: inner">Refresh</button>

<!-- POST and append the response -->
<button sender="feed post: /api/posts apply: append">Add</button>

<!-- DELETE and replace outer HTML (removes element) -->
<button sender="item delete: /api/posts/1 apply: outer">Remove</button>

Message Composition

Messages can be composed using pipes and semicolons for complex workflows.

Pipes — sequential chaining

The | operator chains messages sequentially. The result of each step is passed to the next:

<button sender="content get: /search | content apply: inner">
  Search
</button>

Semicolons — parallel independent chains

The ; operator runs multiple independent message chains in parallel:

<button sender="sidebar get: /nav apply: inner; main get: /home apply: inner">
  Reset
</button>

Both fetches happen simultaneously. Neither depends on the other.

URL History

The push-url attribute on a sender updates the browser's URL via history.pushState when the message is dispatched:

<a href="/about"
   sender="content get: /partials/about.html apply: inner"
   push-url="/about">
  About
</a>

When the user navigates back or forward with browser buttons, talkDOM replays the associated sender message, restoring the page state without a full reload.

The href serves as a fallback for non-JS environments and right-click "open in new tab".

Polling

Receivers can automatically refresh their content at a set interval using the poll: keyword in the receiver attribute:

<div receiver="status get: /api/status apply: inner poll: 5s"></div>

This fetches /api/status every 5 seconds and replaces the element's inner HTML with the response.

Polling stops automatically when the element is removed from the DOM.

Persistence

Add the persist attribute to a receiver to save its content to localStorage:

<div receiver="preferences" persist></div>

Content is saved whenever it changes and restored automatically on page load. Useful for user preferences, draft content, or UI state that should survive page refreshes.

Server Triggers

Servers can fire client-side talkDOM messages by including the X-TalkDOM-Trigger response header:

X-TalkDOM-Trigger: notifications get: /api/alerts apply: inner

When talkDOM receives a response with this header, it executes the message as if a sender had been clicked.

CORS

For cross-origin requests, the server must expose the header:

Access-Control-Expose-Headers: X-TalkDOM-Trigger

Request Headers

Every talkDOM request includes these headers, letting the server distinguish partial requests from full page loads:

Header Description
X-TalkDOM-Request Always present. Identifies the request as coming from talkDOM.
X-TalkDOM-Current-URL The current page URL at the time of the request.
X-TalkDOM-Receiver The name of the receiver that will handle the response.

CSRF Protection

POST, PUT, and DELETE requests automatically include an X-CSRF-Token header, read from a meta tag:

<meta name="csrf-token" content="your-token-here">

Lifecycle Events

talkDOM dispatches custom events on receiver elements after operations complete:

talkdom:done

Fired after a successful operation. The detail object includes:

{ receiver, selector, args }

talkdom:error

Fired when an operation fails. The detail object includes:

{ receiver, selector, args, error }

Example

document.querySelector('[receiver="content"]')
  .addEventListener('talkdom:done', (e) => {
    console.log('Updated:', e.detail.receiver);
  });

Programmatic API

Sending messages from JavaScript

Use talkDOM.send() to dispatch messages programmatically. Returns a Promise:

await talkDOM.send("content get: /api/data apply: inner");

Custom methods

Register custom keywords by adding functions to talkDOM.methods:

talkDOM.methods["highlight:"] = function(el, arg) {
  el.style.backgroundColor = arg;
};

// Now usable in sender attributes:
// sender="box highlight: yellow"

Security

talkDOM does not sanitize HTML. You must ensure that server responses are safe before inserting them into the DOM.

CSRF tokens are automatically read from a <meta name="csrf-token"> tag and sent with POST, PUT, and DELETE requests.

Avoid storing sensitive data in receivers that use the persist attribute, as content is saved to localStorage.

Browser Support

talkDOM targets modern browsers. Internet Explorer is not supported.

Browser Minimum Version
Chrome 51+
Firefox 49+
Safari 10+
Edge 79+