title: "Client Interactions" page: interactions section: Interactivity parent: Interactivity parent_href: /docs/interactions

Client Interactions

Fetch HTML from the server and inject it into the page — no JavaScript required. wwwhat handles partial loading, SPA navigation, loading states, and confirmations through HTML attributes.

Fetching HTML

Use w-get or w-post to fetch HTML from a URL and inject the response into a target element. The w-target attribute specifies where the content goes.

<button w-get="/w-partial/items" w-target="#list">Load Items</button>
<div id="list"></div>

When the button is clicked, wwwhat fetches /w-partial/items via GET and injects the response HTML into the #list element.

Use w-post for POST requests:

<button w-post="/w-action/archive" w-target="#status">Archive</button>
<span id="status"></span>

Targeting Elements

The w-target attribute accepts any CSS selector. The response HTML is injected into the first matching element.

<!-- Target by ID -->
<button w-get="/w-partial/stats" w-target="#stats-panel">Refresh</button>

<!-- Target by class -->
<button w-get="/w-partial/alerts" w-target=".alert-container">Check</button>
Note: The w-target attribute is required for w-get and w-post. Without it, the fetch is skipped and a warning is logged to the console.

Swap Modes

The w-swap attribute controls how fetched content is injected into the target. The default is innerHTML, which replaces the target's inner content.

ModeBehavior
innerHTMLReplace the target's inner content (default)
replaceSame as innerHTML
prependInsert before the target's first child
appendInsert after the target's last child
beforeInsert before the target element itself
afterInsert after the target element itself
noneFetch but don't inject — useful for side effects
<!-- Append new items to a list -->
<button w-get="/w-partial/more-items" w-target="#feed" w-swap="append">
  Load More
</button>
<div id="feed">
  <!-- existing items -->
</div>

<!-- Prepend a notification -->
<button w-post="/w-action/notify" w-target="#notifications" w-swap="prepend">
  Send Alert
</button>

Triggers

By default, w-get and w-post fire on click. Use w-trigger to change the triggering event.

ValueFires when
clickElement is clicked (default)
changeInput value changes
submitForm is submitted
<!-- Filter on dropdown change -->
<select w-get="/w-partial/products" w-target="#product-list" w-trigger="change">
  <option value="all">All Categories</option>
  <option value="electronics">Electronics</option>
  <option value="books">Books</option>
</select>
<div id="product-list"></div>

Sending Parameters

Use w-params to send additional parameters with the request. The value is a JSON object.

<button
  w-get="/w-partial/items"
  w-target="#list"
  w-params='{"page": "2", "sort": "newest"}'
>
  Page 2
</button>

For GET requests, parameters are appended as query string values. For POST requests, they are sent as form data.

Including Form Values

Use w-include to send values from a form alongside the request. The value is a CSS selector pointing to a form element.

<form id="search-form">
  <input type="text" name="q" placeholder="Search...">
  <select name="category">
    <option value="all">All</option>
    <option value="posts">Posts</option>
  </select>
</form>

<button
  w-get="/w-partial/search-results"
  w-target="#results"
  w-include="#search-form"
>
  Search
</button>
<div id="results"></div>

All named inputs inside the referenced form are serialized and sent with the request.

SPA Navigation

wwwhat automatically intercepts internal links for instant, client-side navigation. All links with href starting with / are boosted by default — no full page reload, with browser history support.

<!-- These navigate via client-side fetch automatically -->
<a href="/about">About</a>
<a href="/blog/my-post">Read Post</a>

The page content is fetched, the body is swapped, styles are updated, and the URL changes in the browser — all without a full reload. The back/forward buttons work as expected.

Opting out

To disable boosting on a specific link, set w-boost="false":

<!-- Force a full page reload -->
<a href="/download/report.pdf" w-boost="false">Download PDF</a>

<!-- External links are never boosted -->
<a href="https://example.com">External Site</a>

Links to other domains, links with target="_blank", and links with download attributes are never intercepted.

Form boosting

Forms with w-boost or actions starting with /w-action are also handled via AJAX. If the server redirects, the client follows the redirect with a client-side navigation.

<form action="/w-action/create-post" method="post" w-boost>
  <input type="text" name="title" placeholder="Post title">
  <button type="submit" class="btn btn-primary">Create</button>
</form>

Loading States

Use w-loading to add a CSS class to the element while a request is in progress. The class is removed when the response arrives.

<button
  w-get="/w-partial/data"
  w-target="#output"
  w-loading="is-loading"
>
  Fetch Data
</button>

If you omit w-loading, the default class w-loading is added automatically. The loading class is applied to both the triggering element and the target element.

static/styles.css
/* Dim content while loading */
.is-loading {
  opacity: 0.5;
  pointer-events: none;
  transition: opacity 200ms ease;
}

/* Spinner on buttons */
button.is-loading::after {
  content: "";
  display: inline-block;
  width: 0.875em;
  height: 0.875em;
  margin-left: 0.5em;
  border: 2px solid transparent;
  border-top-color: currentColor;
  border-radius: 50%;
  animation: spin 600ms linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

For form submissions, the submit button is automatically disabled and receives the btn-loading class while the request is in flight.

Tip: The built-in btn-loading class in what.css adds a spinner animation to buttons. Use it with w-loading="btn-loading" or let form submissions apply it automatically.

Confirmation Dialogs

Add w-confirm to show a browser confirmation dialog before the request fires. If the user cancels, the action is aborted.

<button
  w-post="/w-action/delete-account"
  w-target="#result"
  w-confirm="Are you sure? This cannot be undone."
  class="btn btn-danger"
>
  Delete Account
</button>

This works on any element with w-get, w-post, or w-trigger actions.

Combining Attributes

All interaction attributes can be combined on a single element. Here is a complete example showing a search interface:

site/search.html
<form id="filters">
  <input type="text" name="q" class="form-input" placeholder="Search...">
  <select name="sort" class="form-select">
    <option value="recent">Most Recent</option>
    <option value="popular">Most Popular</option>
  </select>
</form>

<button
  w-get="/w-partial/results"
  w-target="#results"
  w-swap="innerHTML"
  w-include="#filters"
  w-loading="is-loading"
  class="btn btn-primary"
>
  Search
</button>

<button
  w-get="/w-partial/results"
  w-target="#results"
  w-swap="append"
  w-params='{"page": "2"}'
  w-include="#filters"
  w-loading="is-loading"
  class="btn btn-outline"
>
  Load More
</button>

<div id="results"></div>

Attribute Reference

AttributeValueDescription
w-getURLFetch HTML via GET
w-postURLFetch HTML via POST
w-targetCSS selectorWhere to inject the response
w-swapMode stringHow to inject: innerHTML, replace, prepend, append, before, after, none
w-triggerEvent nameWhen to fire: click, change, submit
w-paramsJSON objectExtra parameters to send
w-includeCSS selectorInclude form values from another element
w-boosttrue / falseEnable or disable SPA navigation on a link or form
w-loadingCSS classClass added during request (default: w-loading)
w-confirmMessage stringShow confirmation dialog before action