Language and directives
This page documents the .wrn language and declarative browser features that span multiple packages.
File anatomy
A file declares a page or component and can contain metadata, props, state, data, view, style, server functions, APIs, and realtime handlers.
page Dashboard {
layout = "default"
seo { title = "Dashboard" }
state count = 0
view { <button @click="count++">{count}</button> }
style { button { padding: 12px; } }
}
State and interpolation
State is scoped to the nearest generated data-scope. Text expressions update reactively after hydration.
state count = 0
state user = { name: "Ada" }
view {
<p>Count: {count}</p>
<p>{user.name}</p>
}
Events
Any DOM event can use @event="statement". The compiler emits data-on-event. The expression receives event and can mutate state.
| Syntax | Purpose |
|---|---|
@click | Pointer or keyboard activation. |
@input | Read live field values. |
@change | React to committed field changes. |
@submit | Handle form submission behavior. |
@browser-click | Run only in a browser target. |
@mobile-click | Run only in a native/mobile target. |
<input @input="name = event.target.value">
<button @click="count++">Add</button>
<form @submit="submitted = true">...</form>
Reactive data attributes
| Directive | Behavior |
|---|---|
data-scope | Declares reactive state for a subtree. |
data-text | Synchronizes textContent with an expression. |
data-show | Shows or hides an element by truthiness. |
data-for | Repeats an element for a client-side list. |
data-on-<event> | Compiled form of an event binding. |
data-component | Mounts a server-rendered component. |
data-slot | Fills a named component or layout slot. |
data-wrnexus-csr | Connects generated client data fetching. |
Conditional rendering
Server conditionals
Server blocks render only the selected branch into the response.
{#if user.isAdmin}
<a href="/admin">Admin</a>
{:else if user}
<p>Welcome {user.name}</p>
{:else}
<a href="/login">Sign in</a>
{/if}Client visibility
<section data-show="open">Visible while open is true</section>
Loops and lists
Server each block
{#each users as user, i}
<p>{i + 1}. {user.name}</p>
{:empty}
<p>No users</p>
{/each}Reactive client loop
<li data-for="item, i in items">
<span data-text="item.name"></span>
<button data-on-click="items = items.filter(x => x !== item)">Remove</button>
</li>
Components, props, and slots
component Card {
props { title = "Card" }
view {
<article><h2>{title}</h2><slot></slot></article>
}
}
<div data-component="card" title="Profile">
<p>Card content</p>
</div>
Server and client data
Use named data bindings for SSR data or client hydration. Secrets and database work stay on the server.
data users {
ssr GET "/api/users"
}
view {
{#each users as user}<p>{user.name}</p>{/each}
}
Forms and validation
Schema-backed forms validate in the browser and on the server with the same descriptor.
<form data-schema="login" method="post" action="/api/login" data-redirect="/dashboard">
<input name="email" type="email">
<span data-error="email"></span>
<button>Sign in</button>
<p data-success="Signed in" hidden></p>
</form>
Internationalization and themes
<h1>{t:home.title}</h1>
<button data-wire-lang-set="fr">Français</button>
<button data-wire-theme-toggle>Toggle theme</button>
<button data-wire-theme-set="dark">Dark</button>
Realtime rooms
<div data-room="chat" data-room-user="Ada">
<span data-room-status></span>
<div data-room-log></div>
<template data-room-item="message"><p>%user%: %text%</p></template>
<form data-room-send><input name="text" data-room-reset></form>
</div>
Browser and native directives
<button data-native-browser="share" data-native-mobile="share"
data-native-options='{"title":"WRNexusJS"}'>Share</button>
<nav data-native-only="mobile">Mobile navigation</nav>
<p data-native-only="browser">Browser instructions</p>
<button data-native-requires="haptics">Haptic action</button>
Other framework attributes
| Attribute | Purpose |
|---|---|
data-error | Field validation error destination. |
data-success | Successful form message. |
data-redirect | Navigation after form success. |
data-room-* | Realtime status, templates, sending, and reset behavior. |
data-uploader | Config-driven upload widget. |
data-wire-theme-* | Theme selection and toggling. |
data-wire-lang* | Language selection. |
data-native-* | Cross-platform capability and visibility behavior. |