v0.14.0
SPA-like navigation with view transitions
Navigate between pages without full page loads. A single persistent Context resets its page-specific state (signals, actions, intervals, subscriptions) on navigate while preserving the SSE connection — no white flash, no reconnection delay.
v.Layout(func(content func() h.H) h.H {
return h.Div(
h.Nav(
h.A(h.Href("/"), h.Text("Home")),
h.A(h.Href("/dashboard"), h.Text("Dashboard")),
),
h.Main(content()),
)
})
v.Page("/dashboard", func(c *via.Context) {
goHome := c.Action(func() { c.Navigate("/", false) })
c.View(func() h.H {
return h.Button(h.Text("Go Home"), goHome.OnClick())
})
})How navigation works
<a href="/path">links — automatically intercepted by Via's injected JS. Opt out individual links withdata-via-no-boostc.Navigate("/path")— programmatic SPA navigation from action handlers- Browser back/forward — handled via
popstate c.Redirect("/path")— unchanged, still does a full page load (escape hatch, external URLs)
New APIs
v.Layout(func(func() h.H) h.H)— optional layout function that wraps every page's view in a shared shell (nav, footer, etc.)c.Navigate(path, popstate)— SPA navigation that resets page state and runs the target page's init function over the existing SSE connectionh.DataViewTransition(name)— setsview-transition-nameon an element for cross-page animation
What resets on navigate
Signals, actions, OnInterval goroutines, pub/sub subscriptions, and fields are all torn down and recreated by the target page's init function. The SSE connection, CSRF token, and session persist.
View Transition API
Navigate uses Datastar's WithViewTransitions() to animate content swaps. Tag elements with h.DataViewTransition("name") to animate matching elements between pages.
Full Changelog: v0.13.0...v0.14.0