Manual
API reference for PrevelteKit. Each section shows the API and a code example.
Stores
Reactive state containers. When a store value changes, all bound DOM elements update automatically.
// Create a store with an initial value
count := p.New(0) // *Store[int]
name := p.New("hello") // *Store[string]
dark := p.New(false) // *Store[bool]
// Read and write
count.Get() // returns current value
count.Set(5) // set new value
count.Update(func(v int) int { // transform current value
return v + 1
})
// Subscribe to changes
count.OnChange(func(v int) {
// called whenever count changes
})Elements & Binding
Build DOM trees with typed element functions. Embed stores directly — they become live text nodes.
// Typed element functions with reactive store interpolation
p.P("Count: ", p.Strong(count))
// Two-way binding for inputs
p.Input(p.Attr("type", "text")).Bind(name) // *Store[string]
p.Input(p.Attr("type", "text")).Bind(age) // *Store[int]
p.Input(p.Attr("type", "checkbox")).Bind(dark) // *Store[bool]
p.Textarea().Bind(notes) // *Store[string]
// Dynamic attributes
p.Div("content").Attr("data-theme", theme)
// Conditional attributes (additive for same attribute name)
p.Div("content").AttrIf("class",
p.Cond(func() bool { return dark.Get() }, dark), "active")
// Raw HTML rendering (not escaped)
p.BindAsHTML(rawHTML)
// Static raw HTML (entities, inline markup)
p.RawHTML("© 2024")Events
Attach event handlers with .On(). Chain modifiers for common patterns.
// Click handler
p.Button("Click").On("click", handler)
// Form submit with preventDefault
p.Form(...).On("submit", handler).PreventDefault()
// Stop event bubbling
p.Button("Inner").On("click", handler).StopPropagation()
// Inline handler
p.Button("+5").On("click", func() {
count.Update(func(v int) int { return v + 5 })
})Conditionals
Show or hide content reactively with p.If(). Supports ElseIf and Else chains.
// Simple if
p.If(p.Cond(func() bool { return count.Get() > 0 }, count),
p.P("Positive"),
)
// If / ElseIf / Else
p.If(p.Cond(func() bool { return score.Get() >= 90 }, score),
p.P("Grade: A"),
).ElseIf(p.Cond(func() bool { return score.Get() >= 80 }, score),
p.P("Grade: B"),
).Else(
p.P("Grade: F"),
)
// p.Cond(predicateFn, ...dependencyStores)Lists
Reactive lists with p.NewList(). Render with p.Each().
// Create a reactive list
items := p.NewList[string]("Apple", "Banana", "Cherry")
// Mutate — triggers re-render
items.Append("Date")
items.RemoveAt(0)
items.Set([]string{"Mango", "Papaya"})
items.Clear()
// Reactive length
items.Len() // *Store[int] — updates automatically
// Render each item
p.Each(items, func(item string, i int) p.Node {
return p.Li(p.Itoa(i), ": ", item)
}).Else(
p.P("No items"),
)Components
Components are Go structs implementing Render() p.Node. Use p.Comp() to embed them.
// Define a component
type Badge struct {
Label *p.Store[string]
}
func (b *Badge) Render() p.Node {
return p.Span(p.Attr("class", "badge"), b.Label)
}
// Scoped CSS
func (b *Badge) Style() string {
return `.badge{background:#007bff;color:#fff}`
}
// Use a component (props are struct fields)
p.Comp(&Badge{Label: p.New("New")})
// Component with slot (child content)
p.Comp(&Card{Title: p.New("Hello")},
p.P("Slot content here"),
)
// Inside the component, render slot content:
p.Slot()
// Callback props for component events
type Button struct {
Label *p.Store[string]
OnClick func()
}
// Shared stores: pass the same *Store to multiple components
theme := p.New("light")
p.Comp(&Header{Theme: theme})
p.Comp(&Sidebar{Theme: theme})
// both components read/write the same storeRouting
Client-side routing with p.NewRouter(). Each route maps to a component and an SSR HTML file.
// Define routes
routes := []p.Route{
{Path: "/", HTMLFile: "index.html", SSRPath: "/", Component: home},
{Path: "/about", HTMLFile: "about.html", SSRPath: "/about", Component: about},
}
// Start the router (in OnMount)
router := p.NewRouter(currentComponent, routes, "unique-id")
router.NotFound(func() { currentComponent.Set(nil) })
router.Start()
// Store[Component] holds the active route component
currentComponent *p.Store[p.Component]
// Links: client-side (default) vs server-side
// <a href="/about">About</a> (SPA navigation)
// <a href="/about" external>About</a> (full page reload)
// Store[Component] for local tabs (non-router):
activeTab := p.New[p.Component](tab1)
activeTab.WithOptions(tab1, tab2, tab3)
activeTab.Set(tab2) // switches displayed componentFetch
Type-safe HTTP requests with automatic JSON encoding/decoding via js struct tags.
// Define response type with js tags
type User struct {
ID int `js:"id"`
Name string `js:"name"`
}
// GET
go func() {
user, err := p.Get[User]("https://api.example.com/user/1")
}()
// POST (send body, decode response)
go func() {
created, err := p.Post[User](url, newUser)
}()
// PUT, PATCH, DELETE
result, err := p.Put[T](url, body)
result, err := p.Patch[T](url, body)
result, err := p.Delete[T](url)
// Advanced: custom headers and abort
signal, abort := p.NewAbortController()
go func() {
result, err := p.Fetch[T](url, &p.FetchOptions{
Method: "GET",
Headers: map[string]string{"Authorization": "Bearer token"},
Signal: signal,
})
}()
abort() // cancel the requestStorage
Persist state to localStorage. LocalStore auto-syncs on every Set().
// Auto-persisted store (syncs on every Set)
theme := p.NewLocalStore("theme", "light")
theme.Set("dark") // automatically saved to localStorage
theme.Store // *Store[string] — use in any element like any store
// Manual localStorage API
p.SetStorage("notes", "hello")
saved := p.GetStorage("notes")
p.RemoveStorage("notes")
p.ClearStorage()Timers
Debounce, throttle, setTimeout, and setInterval — all return cleanup functions.
// Debounce: fires after idle period
doSearch, cleanup := p.Debounce(300, func() {
// fires 300ms after last call
})
doSearch() // call repeatedly — only last one fires
cleanup() // cancel pending
// Throttle: max once per interval
onClick := p.Throttle(500, func() {
// max once per 500ms
})
// SetTimeout: fires once after delay
cancel := p.SetTimeout(2000, func() {
// fires after 2 seconds
})
cancel() // cancel before it fires
// SetInterval: fires repeatedly
stop := p.SetInterval(60000, func() {
// fires every 60 seconds
})
stop() // stop the intervalLifecycle
Components can implement lifecycle hooks for setup and teardown.
// OnMount: called when component becomes active
func (c *MyComp) OnMount() {
if p.IsBuildTime {
return // skip side effects during SSR
}
// fetch data, start timers, etc.
}
// OnDestroy: called when component is removed (e.g. route change)
func (c *MyComp) OnDestroy() {
if c.stopTimer != nil {
c.stopTimer()
}
}
// New: constructor — create stores, initialize state
func (c *MyComp) New() p.Component {
return &MyComp{
Count: p.New(0),
Name: p.New(""),
}
}
// GlobalStyle: CSS applied to entire page (on App component)
func (a *App) GlobalStyle() string { return `body{margin:0}` }
// Style: scoped CSS (auto-prefixed to this component)
func (c *MyComp) Style() string { return `.btn{color:red}` }
// p.IsBuildTime: true during SSR, false in WASM
// Use to guard browser-only code (fetch, timers, DOM access)