One module per page: render, event handlers, stream callbacks, and colocated function components.
defmodule MyAppWeb.CounterPage do
use Dstar.Page
def mount(conn, _params), do: assign(conn, count: 0)
def render(assigns) do
~H"""
<div data-signals:count={@count}>
<button data-on:click={event("increment")}>+1</button>
</div>
"""
end
def handle_event(conn, "increment", signals) do
patch_signals(conn, %{count: (signals["count"] || 0) + 1})
end
endRoute it with Dstar.Router.dstar/2:
import Dstar.Router
dstar "/counter", MyAppWeb.CounterPageAll requests are driven by Dstar.Page.Plug — pages contain no
control flow, only callbacks. Conn in, conn out.
Options
:idle_check— ms between connection liveness checks in the stream loop (default30_000).
Summary
Callbacks
Stream open: subscribe to topics, assign loop state. Optional —
defining it enables POST /path streaming.
Handles a Datastar event POST. SSE is already started. Optional.
Handles one message from the library-owned receive loop. Optional.
GET: load data and assign what render/1 needs. Optional.
The full-page HEEx template. Required.
If defined, the stream opens via Dstar.start_stream/2 keyed on the result. Optional.
Callbacks
@callback handle_connect(Plug.Conn.t(), params :: map()) :: Plug.Conn.t()
Stream open: subscribe to topics, assign loop state. Optional —
defining it enables POST /path streaming.
@callback handle_event(Plug.Conn.t(), event :: String.t(), signals :: map()) :: Plug.Conn.t()
Handles a Datastar event POST. SSE is already started. Optional.
@callback handle_info(msg :: term(), Plug.Conn.t()) :: Plug.Conn.t() | {:halt, Plug.Conn.t()}
Handles one message from the library-owned receive loop. Optional.
@callback mount(Plug.Conn.t(), params :: map()) :: Plug.Conn.t()
GET: load data and assign what render/1 needs. Optional.
@callback render(assigns :: map()) :: Phoenix.LiveView.Rendered.t()
The full-page HEEx template. Required.
@callback stream_key(Plug.Conn.t()) :: term()
If defined, the stream opens via Dstar.start_stream/2 keyed on the result. Optional.