what

Lazy Loading & Polling

The <what-fetch> tag declares a region of the page that fills itself from a partial — on render, when scrolled into view, on a timer, or on click. No fetch(), no setInterval, no observers to write.

The three canonical forms

<!-- fetch on page render (the default) -->
<what-fetch url="/w-partial/time"/>

<!-- lazy: fetch the first time it scrolls into view -->
<what-fetch url="/w-partial/comments" when="visible">Loading…</what-fetch>

<!-- live: refresh every 5 seconds -->
<what-fetch url="/w-partial/stats" poll="5s">
  <include src="partials/stats"/>
</what-fetch>

Children are the region's initial content — server-render the first state with an <include> so the page is complete before any fetch happens, or use a lightweight placeholder for lazy regions.

Attributes

AttributeDefaultMeaning
urlrequiredWhat to fetch — usually a /w-partial/… path. #var# interpolates.
whenloadload (on render), visible (first scroll into view), click
pollRefresh interval: 500ms, 5s, 2m, 1h, or bare seconds. Combines with when.
methodgetget or post
targetitselfCSS selector to inject into, if not the region itself
swapinnerHTMLinnerHTML, outerHTML, prepend, append, before, after, none
asdivWrapper element, e.g. as="tbody" inside a table
params, include, loading, confirmPass through to w-params, w-include, w-loading, w-confirm

Anything else (class, id, style, aria-*…) is copied onto the wrapper verbatim.

The raw attribute form

<what-fetch> is sugar: the server expands it to the w-* attributes, which you can also write directly on any element. These are equivalent:

<what-fetch url="/w-partial/stats" poll="5s">…</what-fetch>

<div class="w-fetch" w-get="/w-partial/stats" w-trigger="load, poll 5s">…</div>

w-trigger for w-get/w-post elements accepts load, revealed, poll <interval>, and click, comma-combinable. Without w-target the element injects into itself. The framework manages every timer and observer: they're cancelled when the element leaves the DOM, paused while the tab is hidden, and a slow response never stacks requests.

Polling vs. Wired State

Polling is pull: the browser asks on a schedule. It's right for data the server doesn't know changed — external APIs, aggregations, anything without an event. For shared app state that your server mutates, prefer Wired State: it's push — one WebSocket message updates every client instantly, with no wasted requests. A useful pairing: w-watch re-fetches a partial when a wired variable changes.

Events

The region fires w:load after each successful swap and w:error (plus a w-fetch-error class) on failure. A failed poll tick keeps the last good content — the region never degrades to an error message on a transient blip.

Things to know

  • Be kind to your server. Every polling region on every open tab is a request stream. Prefer intervals in seconds, not milliseconds; prefer Wired State when you control the mutation.
  • Don't self-destruct. when="load" with swap="outerHTML" and no target replaces the region with the response, which re-arms and fetches again — an infinite loop. The dev console warns about this combination.
  • Static builds have no server. On a run-what build export there is no /w-partial/* endpoint — regions keep their initial children. Design the fallback content accordingly.