Core Concepts
Understand the fundamental building blocks of GoliveKit.
Component Interface
Every GoliveKit component implements the core.Component interface:
pkg/core/component.go
type Component interface {
// Name returns the unique component identifier
Name() string
// Mount is called when the component is first loaded
Mount(ctx context.Context, params Params, session Session) error
// Render returns the HTML representation
Render(ctx context.Context) Renderer
// HandleEvent processes user interactions
HandleEvent(ctx context.Context, event string, payload map[string]any) error
// Terminate is called when the component is destroyed
Terminate(ctx context.Context, reason TerminateReason) error
}Component Lifecycle
┌─────────────────────────────────────────────────────────────┐
│ HTTP REQUEST │
│ │ │
│ ▼ │
│ Mount() │
│ │ │
│ ▼ │
│ Render() │
│ │ │
│ ▼ │
│ HTML Response │
└─────────────────────────────────────────────────────────────┘
│
│ WebSocket Connect
▼
┌─────────────────────────────────────────────────────────────┐
│ INTERACTIVE PHASE │
│ │ │
│ ┌──────────────┴──────────────┐ │
│ │ │ │
│ ▼ │ │
│ HandleEvent() │ │
│ │ │ │
│ ▼ │ │
│ Render() │ │
│ │ │ │
│ ▼ │ │
│ Compute Diff ──────────────────────►│ │
│ │ │ │
│ ▼ │ │
│ Send to Client │ │
│ │ │ │
│ └─────────────────────────────┘ │
│ │ │
│ │ Disconnect │
│ ▼ │
│ Terminate() │
└─────────────────────────────────────────────────────────────┘BaseComponent
Use core.BaseComponent to get common functionality:
counter.go
type Counter struct {
core.BaseComponent // Provides Assigns(), Socket(), etc.
Count int
}
func (c *Counter) Mount(ctx context.Context, params core.Params, session core.Session) error {
c.Count = 0
// Access assigns
c.Assigns().Set("initialized", true)
return nil
}Assigns (State)
Assigns is a thread-safe key-value store for component state:
assigns.go
// Set a value
c.Assigns().Set("user", user)
c.Assigns().Set("items", items)
c.Assigns().Set("loading", false)
// Get a value
user := c.Assigns().Get("user")
// Get with type assertion
if user, ok := c.Assigns().Get("user").(*User); ok {
fmt.Println(user.Name)
}
// Check if key exists
if c.Assigns().Has("user") {
// Key exists
}
// Delete a key
c.Assigns().Delete("user")
// Clone for safe iteration
snapshot := c.Assigns().Clone()Socket
The Socket provides access to the WebSocket connection:
socket.go
// Send a message to the client
c.Socket().Send("event_name", map[string]any{
"message": "Hello!",
})
// Push a redirect
c.Socket().Redirect("/dashboard")
// Get the socket ID
id := c.Socket().ID()Rendering
The Render method returns HTML using the Renderer interface:
render.go
func (c *Counter) Render(ctx context.Context) core.Renderer {
return core.RendererFunc(func(ctx context.Context, w io.Writer) error {
// Use data-live-view to identify the component
// Use data-slot for efficient partial updates
fmt.Fprintf(w, `
<div data-live-view="counter">
<h1>Count: <span data-slot="count">%d</span></h1>
<button lv-click="increment">+</button>
<button lv-click="decrement">-</button>
</div>
`, c.Count)
return nil
})
}Important attributes:
data-live-view="name"- Identifies the LiveView component rootdata-slot="id"- Marks regions for efficient partial updates