Live View
Build reactive, real-time interfaces without writing JavaScript. Live View renders components on the server and efficiently updates the DOM over WebSockets.
See it in action
Try the interactive counter demo on our landing page.
How It Works
Live View is a server-rendered component system that maintains state on the server. When users interact with the page, events are sent over WebSockets, the server updates the component state, re-renders the template, and sends back only the differences (diffs) to update the DOM.
Creating a Live View Component
Step 1: Create the Template
Create a .sliv file in app/views/live/. Use @variable syntax for reactive state.
<div class="counter-component">
<h2>Count: @count</h2>
<button soli-click="decrement">-</button>
<button soli-click="increment">+</button>
</div>
Step 2: Register the Route
Register your Live View component in config/routes.sl using the router_live function.
# Register LiveView components
router_live("counter", "live#counter");
router_live("metrics", "live#metrics");
Step 3: Create the Controller
Create a controller that handles events. The handler receives an event hash with event (name), params, and state. Return the new state as a hash.
# Counter component handler
def counter(event_data: Any) let event = event_data["event"]; # Event name (e.g., "increment")
let params = event_data["params"]; # Event parameters
let state = event_data["state"]; # Current component state
let count = state["count"];
if (count == null)
count = 0;
end
if (event == "increment")
return { "count": count + 1 };
end
if (event == "decrement")
return { "count": count - 1 };
end
# Return unchanged state for unknown events
state
end
Available Directives
soli-click
Triggers on element click. <button soli-click="save">
soli-submit
Triggers on form submission. <form soli-submit="create">
soli-change
Triggers on input value change. <select soli-change="filter">
soli-keydown
Triggers on key press. <input soli-keydown="search">
soli-keyup
Triggers on key release. <input soli-keyup="validate">
soli-focus
Triggers when element gains focus. <input soli-focus="highlight">
soli-blur
Triggers when element loses focus. <input soli-blur="validate">
soli-value-*
Binds input value to state. <input soli-value-name>
soli-target
Specifies target component for updates. <div soli-target="results">
soli-debounce
Debounces event by ms. <input soli-keyup="search" soli-debounce="300">
State Management
State is stored on the server and accessed in templates using @variable syntax. The server maintains state between events.
<!-- Simple variable -->
<span>Hello, @username</span>
<!-- Conditional rendering -->
<% if @logged_in %>
<a href="/logout">Sign Out</a>
<% else %>
<a href="/login">Sign In</a>
<% end %>
<!-- Iteration -->
<% for item in @items %>
<li><%= item["name"] %></li>
<% end %>
Client Setup
Include the Live View client library and mount your component.
<!-- Include the Live View client (~2KB gzipped) -->
<script src="/js/live.js"></script>
<!-- Mount a Live View component -->
<div id="counter" data-live-view="counter"></div>
<script>
# Initialize Live View
SoliLive.connect();
</script>
Route Configuration
Register the Live View WebSocket endpoint in your routes.
# Live View WebSocket endpoint
router_live("/live/counter", "live#counter");
High-Rate Updates
Live View supports server-pushed updates for real-time dashboards, monitoring, and live data feeds.
Use the tick event type to push updates at high frequencies (up to 60 updates/second).
def metrics_dashboard(event: Any) let type = event["type"];
if (type == "connect")
# Set tick interval in milliseconds (50ms = 20 updates/sec)
return {
"state": { "cpu": 0, "memory": 0, "requests": 0 },
"tick_interval": 50
};
end
if (type == "tick")
# Server pushes fresh data on each tick
return {
"state": {
"time": datetime_now(),
"cpu": system_cpu_usage(),
"memory": system_memory_mb(),
"requests": request_counter()
}
};
end
{}
end
<div class="dashboard">
<div class="metric">
<span class="label">Server Time</span>
<span class="value">@time</span>
</div>
<div class="metric">
<span class="label">CPU</span>
<span class="value">@cpu%</span>
</div>
<div class="metric">
<span class="label">Memory</span>
<span class="value">@memory MB</span>
</div>
<div class="metric">
<span class="label">Requests/sec</span>
<span class="value">@requests</span>
</div>
</div>
Tick Intervals
- 1000ms - Good for dashboards, status pages
- 100ms - Good for live charts, activity feeds
- 50ms (20/s) - Good for real-time monitoring
- 16ms (60/s) - Maximum rate, use sparingly for animations
Performance
Why Live View?
- No JavaScript required - Build interactive UIs with just server-side code
- SEO friendly - Initial HTML is server-rendered
- Reduced complexity - No client-side state management to maintain
- Real-time by default - WebSocket connection enables instant updates