State Management

What handles state server-side by default, but provides client-side features for persistence and navigation state.

Application vs Session Data

Application data is shared by all users, while session data is unique to each visitor.

Application Counter

Shared by all users

0

Session Counter

Unique to your session

0
// In application.what // Expose application data (shared) data.application = ["app_counter"] // Expose session data (per-user) data.session = ["counter"] // In templates 0 0

SPA Navigation

Links are intercepted for single-page app navigation. Pages are cached for instant back/forward navigation.

  • Click any link for AJAX-powered navigation
  • Browser back/forward buttons work normally
  • Pages cached for 5 minutes by default
  • Loading state shown during navigation
// Clear the page cache What.clearCache(); // Navigate programmatically What.navigateTo('/other-page');

Element Persistence

Use w-persist to keep elements across page navigations. Useful for audio players, sidebars, or other persistent UI.

Elements with w-persist are preserved when navigating between pages. The element's state (including audio/video playback position) is maintained.

<div w-persist="audio-player"> <audio src="music.mp3"></audio> </div> <!-- Sidebar that stays visible --> <aside w-persist="sidebar"> Navigation content... </aside>

Navigation State

Use data-active on navigation containers to automatically highlight the current page link.

Links automatically receive an active class when they match the current URL.

<nav data-active="home"> <a href="/" data-page="home">Home</a> <a href="/about" data-page="about">About</a> </nav>

Form Handling

Forms can be submitted via AJAX with partial page updates, or use traditional full-page navigation.

  • w-target="selector" - Update specific element with response
  • w-reset - Reset form after successful submission
  • w-confirm="message" - Show confirmation before submit
<form action="/api/data" w-target="#results" w-reset> <input name="query"> <button type="submit">Search</button> </form> <div id="results"></div>

Session Management

What provides automatic session management with secure cookie-based session IDs.

Your Session ID:
ad81ee87580355bcd8d08c203a887ae3d04c650d6d30d395b8240e2a2da34181fabb74137c8c8a0aff72778cf64ba609dd5ff10c677231e2ca6c89a222e60c2e
  • 128-char secure session ID
  • HttpOnly, SameSite=Strict cookies
  • SQLite storage for persistence
  • Configurable expiration (default: 7 days)
<!-- Access session data in templates --> Session ID: ad81ee87580355bcd8d08c203a887ae3d04c650d6d30d395b8240e2a2da34181fabb74137c8c8a0aff72778cf64ba609dd5ff10c677231e2ca6c89a222e60c2e Created: 2026-02-04T18:29:54.360601381+00:00 <!-- Configure in wwwhat.toml --> [session] enabled = true cookie_name = "w_session" max_age = 604800 # 7 days secure = false # true in production

Server-Side State

Most state lives on the server in the DataStore. Templates render with the current state on each request.

  • Data stored in JSON files
  • Available in templates via #collection.field#
  • CRUD operations via w-action endpoints
  • Server-side caching for performance
<!-- Display data from collections --> <loop data="#posts#" as="post"> <h2>#post.title#</h2> <p>#post.content#</p> </loop> <!-- CRUD operations --> <form action="/w-action/posts?w-action=create"> ... </form>