Examples

Live Examples

Every sandbox on this page is a real Wizz component, server-rendered with the page and hydrated in your browser. The source beside each one is what runs.

Persisted counter

persist() state with a replaying animation. Open this page in two tabs and click in one.

Live · Counter.wizz

Synced across tabs

0

doubled 0 · parity even

Counter.wizz (excerpt)
<script>
  export let label = "Live counter";
  let count = persist("wizz_docs_counter", 0);
  let bump = "value";
  let flip = false;

  function increment() {
    count += 1;
    flip = !flip;
    bump = flip ? "value bump-a" : "value bump-b";   // replay the animation
  }
</script>

<div class="counter">
  <p class="label">{label}</p>
  <output class={bump} aria-live="polite">{count}</output>
  <button type="button" on:click={increment} aria-label="Increment">+</button>
</div>

Keyed todo list

Keyed {#each}, event delegation, a submit handler, CSS-driven filters, and persisted state.

Live · TodoDemo.wizz

  • Read the component contract
  • Build a keyed list
  • Ship with zero dependencies
TodoDemo.wizz (excerpt)
<script>
  let todos = persist("wizz_docs_todos", []);
  let filter = "all";

  function row(item) {
    return { ...item, rowClass: item.done ? "item is-done" : "item" };
  }

  function handleListClick(event) {
    const node = event.target.closest("[data-id]");
    if (!node) return;
    const id = Number(node.dataset.id);
    if (event.target.closest("[data-action='remove']")) {
      todos = todos.filter((item) => item.id !== id);
    } else {
      todos = todos.map((item) => (item.id === id ? row({ ...item, done: !item.done }) : item));
    }
  }
</script>

<div class="todo" data-filter={filter}>
  <ul on:click={handleListClick}>{#each todos as item (item.id)}<li class={item.rowClass} data-id={item.id}><span>{item.title}</span><button data-action="remove">×</button></li>{/each}</ul>
</div>

<wizz:style>
  [data-filter="active"] .is-done { display: none; }
</wizz:style>

Parent → child props

The parent owns state and precomputes every value; the child only renders. Props flow through setProps() — the child is never remounted.

Live · PropsDemo.wizz → Meter.wizz

Parent → child prop updates: 0 · the child is never remounted.

CPU budget40%
Meter.wizz
<script>
  // Meter.wizz — a pure view: every value is a prop.
  export let label = "Meter";
  export let value = 0;
  export let barStyle = "";
  export let meterClass = "meter calm";
</script>

<div class={meterClass}>
  <span>{label}</span><span>{value}%</span>
  <div class="rail"><span class="fill" style={barStyle}></span></div>
</div>

Lifecycle clock

onMount starts an interval after hydration; onDestroy clears it when the page is torn down. The server renders the placeholder.

Live · LiveClock.wizz

onMount started an interval · 0 ticks · onDestroy clears it

LiveClock.wizz
<script>
  let time = "--:--:--";
  let ticks = 0;
  let timerId = null;

  function tick() {
    time = new Date().toLocaleTimeString();
    ticks += 1;
  }

  onMount(() => {
    tick();
    timerId = setInterval(tick, 1000);
  });

  onDestroy(() => {
    clearInterval(timerId);
  });
</script>

<div class="clock">
  <time>{time}</time>
  <p>{ticks} ticks</p>
</div>

Server API call

A component calling a handler in src/server/api/, with an AbortController released on destroy.

Live · ApiDemo.wizz → /api/greet

idle—

// Press “Call /api/greet” — the handler runs on the server.
ApiDemo.wizz (excerpt)
<script>
  let name = "Ada";
  let output = "Press the button";
  let controller = null;

  async function callApi(event) {
    event.preventDefault();
    controller?.abort();
    controller = new AbortController();
    const response = await fetch("/api/greet?name=" + encodeURIComponent(name), {
      signal: controller.signal
    });
    output = JSON.stringify(await response.json(), null, 2);
  }

  onDestroy(() => {
    controller?.abort();
  });
</script>

<form on:submit={callApi}>
  <button type="submit">Call /api/greet</button>
  <pre>{output}</pre>
</form>

This site

The documentation itself is the largest example: 24 components and pages, server-rendered and hydrated, with no runtime dependency beyond the Wizz runtime the build copies into dist/.

wizz-documentation
src/
├── App.wizz                    landing page: hero, live counter, feature grid
├── components/
│   ├── TopNav.wizz             capsule dock, Ctrl+K spotlight (<dialog>), theme, persist()
│   ├── Sidebar.wizz            <details> groups, view-transition pill
│   ├── Toc.wizz                scroll spy + sliding indicator
│   ├── CodeBlock.wizz          zero-dependency highlighter + copy feedback
│   ├── ApiEntry.wizz           reference entries (params table + example)
│   ├── Callout.wizz · PageNav.wizz
│   └── Counter · TodoDemo · PropsDemo · Meter · LiveClock · ApiDemo
├── pages/docs/*.wizz           one routed page per topic
└── server/api/greet.js         the handler behind the fetch demo