feat: add Redirect and ReplaceURL methods for browser navigation

Add SSE-based navigation methods to Context:
- Redirect(url) / Redirectf() - navigate to new page
- ReplaceURL(url) / ReplaceURLf() - update URL without navigation

Update session example to demonstrate full login flow with redirects.
This commit is contained in:
Ryan Hamamura
2026-01-12 00:47:52 -10:00
parent 9a23188973
commit 03b6d7453a
3 changed files with 97 additions and 17 deletions

View File

@@ -7,11 +7,11 @@ import (
func main() {
v := via.New()
v.Config(via.Options{ServerAddress: ":7331"})
v.Page("/", func(c *via.Context) {
username := c.Session().GetString("username")
// Login page
v.Page("/login", func(c *via.Context) {
flash := c.Session().PopString("flash")
usernameInput := c.Signal("")
login := c.Action(func() {
@@ -20,38 +20,69 @@ func main() {
c.Session().Set("username", name)
c.Session().Set("flash", "Welcome, "+name+"!")
c.Session().RenewToken()
c.Redirect("/dashboard")
}
c.Sync()
})
logout := c.Action(func() {
c.Session().Set("flash", "Goodbye!")
c.Session().Delete("username")
c.Sync()
})
c.View(func() h.H {
// Already logged in? Redirect to dashboard
if c.Session().GetString("username") != "" {
c.Redirect("/dashboard")
return h.Div()
}
var flashMsg h.H
if flash != "" {
flashMsg = h.P(h.Text(flash), h.Style("color: green"))
}
return h.Div(
flashMsg,
h.H1(h.Text("Login")),
h.Input(h.Type("text"), h.Placeholder("Username"), usernameInput.Bind()),
h.Button(h.Text("Login"), login.OnClick()),
)
})
})
// Dashboard page (protected)
v.Page("/dashboard", func(c *via.Context) {
logout := c.Action(func() {
c.Session().Set("flash", "Goodbye!")
c.Session().Delete("username")
c.Redirect("/login")
})
c.View(func() h.H {
username := c.Session().GetString("username")
// Not logged in? Redirect to login
if username == "" {
return h.Div(
flashMsg,
h.H1(h.Text("Login")),
h.Input(h.Type("text"), h.Placeholder("Username"), usernameInput.Bind()),
h.Button(h.Text("Login"), login.OnClick()),
)
c.Session().Set("flash", "Please log in first")
c.Redirect("/login")
return h.Div()
}
flash := c.Session().PopString("flash")
var flashMsg h.H
if flash != "" {
flashMsg = h.P(h.Text(flash), h.Style("color: green"))
}
return h.Div(
flashMsg,
h.H1(h.Textf("Hello, %s!", username)),
h.H1(h.Textf("Dashboard - Hello, %s!", username)),
h.P(h.Text("Your session persists across page refreshes.")),
h.Button(h.Text("Logout"), logout.OnClick()),
)
})
})
// Redirect root to login
v.Page("/", func(c *via.Context) {
c.View(func() h.H {
c.Redirect("/login")
return h.Div()
})
})
v.Start()
}