This fake IM keeps the message list and composer server-shaped.
NowInteractive examples
Show the pattern, not a framework maze.
Each example is a concrete RGX application. Start with the Visual tab, then switch to Trigger HTML or Handler to see how a thin browser can still drive a full interface.
The examples page highlights the projects already using RGX in production.
Conversation demo
Fake IM
A chat-style interface with a thin composer and a server-shaped thread.
Fake IM
Conversation UI
Keep the composer thin and let the thread update as a single server-shaped surface.
Ready
Trigger HTML
RGX trigger and selector map
The HTML tab shows the request trigger and the selectors RGX uses to update the page.
{{define "example-chat"}}
<section
class="tool-shell tool-shell-accent"
id="chat-shell"
data-example-tool="chat"
data-gx-url="/fragments/examples/chat"
data-gx-select="#chat-shell@outerHTML->#chat-shell@outerHTML #chat-thread@innerHTML->#chat-thread@innerHTML #chat-status@innerHTML->#chat-status@innerHTML"
>
<header class="tool-shell-head">
<div>
<p class="eyebrow">Fake IM</p>
<h3>Conversation UI</h3>
<p>Post the message to one route, then let RGX replace the thread and status together.</p>
</div>
<span class="tool-chip">RGX</span>
</header>
<div class="im-shell">
<div class="im-thread" id="chat-thread" data-im-thread aria-live="polite">
<article class="im-message im-message-agent" data-im-author="agent">
<strong>RGX Support</strong>
<p>This fake IM keeps the message list server-authored and the browser thin.</p>
<small>Now</small>
</article>
<article class="im-message im-message-self" data-im-author="self">
<strong>You</strong>
<p>Can RGX keep chat interfaces thin?</p>
<small>Now</small>
</article>
</div>
<div class="im-composer">
<label class="tool-field">
<span>Message</span>
<textarea name="message" data-im-input spellcheck="false">RGX keeps chat interfaces thin.</textarea>
</label>
<div class="tool-actions">
<button type="submit" class="tool-button" data-im-send>Send</button>
<button type="button" class="tool-button tool-button-ghost" data-im-reply>Quick reply</button>
</div>
<div class="tool-status" id="chat-status" data-example-status>
<span class="tool-spinner" aria-hidden="true"></span>
<span data-example-status-text>Ready</span>
</div>
</div>
</div>
</section>
{{end}}
Handler
Server response and headers
The handler tab shows the route code that returns the same UI with RGX headers and presets.
func (a *App) sendMessage(w http.ResponseWriter, r *http.Request) {
message := strings.TrimSpace(r.FormValue("message"))
thread := chatStore.ForConversation(r.Context())
if message == "" {
w.WriteHeader(http.StatusUnprocessableEntity)
}
thread.AddUserMessage(message)
thread.AddAgentMessage("One response can update the thread and the composer together.")
w.Header().Set("Recyclr-Use-Presets", "chat")
w.Header().Set("Recyclr-Event", "updated")
renderTemplate(w, "examples/chat", map[string]any{
"Thread": thread,
"Status": "Sent",
})
}