What handles state server-side by default, but provides client-side features for persistence and navigation state.
Application data is shared by all users, while session data is unique to each visitor.
Shared by all users
Unique to your session
// In application.what
// Expose application data (shared)
data.application = ["app_counter"]
// Expose session data (per-user)
data.session = ["counter"]
// In templates
#data.application.app_counter#
#data.session.counter#
Links are intercepted for single-page app navigation. Pages are cached for instant back/forward navigation.
// Clear the page cache
What.clearCache();
// Navigate programmatically
What.navigateTo('/other-page');
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>
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>
Forms can be submitted via AJAX with partial page updates, or use traditional full-page navigation.
w-target="selector" - Update specific element with responsew-reset - Reset form after successful submissionw-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>
What provides automatic session management with secure cookie-based session IDs.
<!-- Access session data in templates -->
Session ID: #session.id#
Created: #session.created_at#
<!-- Configure in wwwhat.toml -->
[session]
enabled = true
cookie_name = "w_session"
max_age = 604800 # 7 days
secure = false # true in production
Most state lives on the server in the DataStore. Templates render with the current state on each request.
#collection.field#w-action endpoints<!-- 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>