WebSockets

irgo supports real-time updates via WebSockets using HTMX's WebSocket extension. This enables live dashboards, chat applications, and collaborative features.

HTMX WebSocket Extension

HTMX provides a built-in WebSocket extension that makes it easy to receive server-pushed HTML updates.

templ LiveDashboard() {    <div hx-ext="ws" ws-connect="/ws/dashboard">        <div id="live-stats">            Loading...        </div>    </div>}

Server-Side Hub

irgo includes a WebSocket hub for managing connections and broadcasting messages:

import "github.com/stukennedy/irgo/pkg/websocket"// Create hubhub := websocket.NewHub()go hub.Run()// Handle WebSocket connectionsr.GET("/ws/dashboard", func(ctx *router.Context) (string, error) {    hub.HandleWebSocket(ctx.ResponseWriter, ctx.Request)    return "", nil})

Broadcasting Updates

// Broadcast HTML to all connected clientshub.Broadcast([]byte(`    <div id="live-stats" hx-swap-oob="true">        <p>Users online: 42</p>        <p>Active sessions: 128</p>    </div>`))// Send to specific sessionhub.SendToSession(sessionID, []byte(html))
Note

Use hx-swap-oob="true" on elements to update them out-of-band. The element's ID determines where the update is applied.

Chat Example

templates/chat.templ
templ ChatRoom(roomID string) {    <div class="chat-room" hx-ext="ws" ws-connect={ "/ws/chat/" + roomID }>        <div id="messages" class="messages">            // Messages will be inserted here        </div>        <form ws-send class="chat-form">            <input type="text" name="message" placeholder="Type a message..." />            <button type="submit">Send</button>        </form>    </div>}templ ChatMessage(user string, message string, timestamp time.Time) {    <div id="messages" hx-swap-oob="beforeend">        <div class="message">            <strong>{ user }</strong>            <span>{ message }</span>            <time>{ timestamp.Format("3:04 PM") }</time>        </div>    </div>}
handlers/chat.go
func HandleChat(ctx *router.Context) (string, error) {    roomID := ctx.Param("roomID")    hub.HandleWebSocket(ctx.ResponseWriter, ctx.Request,        websocket.WithRoom(roomID),        websocket.WithMessageHandler(func(session *websocket.Session, msg []byte) {            var data struct {                Message string `json:"message"`            }            json.Unmarshal(msg, &data)            html := renderer.RenderToString(templates.ChatMessage(                session.UserID,                data.Message,                time.Now(),            ))            hub.BroadcastToRoom(roomID, []byte(html))        }),    )    return "", nil}

Live Notifications

templ NotificationListener() {    <div hx-ext="ws" ws-connect="/ws/notifications">        <div id="notification-badge">0</div>        <div id="notification-list"></div>    </div>}templ Notification(n Notification) {    // Update badge count    <span id="notification-badge" hx-swap-oob="true">        { fmt.Sprintf("%d", n.UnreadCount) }    </span>    // Prepend new notification    <div id="notification-list" hx-swap-oob="afterbegin">        <div class="notification">            <p>{ n.Message }</p>            <time>{ n.CreatedAt.Format("3:04 PM") }</time>        </div>    </div>}

Next Steps