Routing and APIs
Route code in Vango is intentionally thin. Page handlers select views. Stateful logic belongs in components.
File-based routing
Vango scans app/routes and maps files to routes.
Examples:
app/routes/index.go -> /
app/routes/about.go -> /about
app/routes/projects/index.go -> /projects
app/routes/projects/id_/index.go -> /projects/:id
app/routes/docs/path___/index.go -> /docs/*path
Use parameter directories like id_ and path___ for Go-friendly imports.
Page handler signatures
Supported shapes:
1func Page(ctx vango.Ctx) *vango.VNode
2func Page(ctx vango.Ctx, p Params) *vango.VNode
Rules:
parse params
choose the page component
return the view
Do not put blocking I/O, signal allocation, or imperative navigation in the page handler.
Params
Use typed params with struct tags.
1type Params struct {
2 ID int `param:"id"`
3}
Use route params for IDs, slugs, UUIDs, and catch-all segments. Use URL params for filters, sorting, and shareable view state.
Layouts
Layouts are pure view wrappers.
1func Layout(ctx vango.Ctx, children vango.Slot) *vango.VNode
Good layout responsibilities:
shell structure
navigation
asset tags
persistent banners
runtime script injection
If a layout needs state, embed a Setup component within it.
Navigation
Prefer declarative navigation for normal user flows.
1Link("/projects", Text("Projects"))
2NavLink(ctx, "/settings", Text("Settings"))
Use ctx.Navigate(...) from event handlers, OnMount, or Effect when navigation is driven by state.
Do not call ctx.Navigate(...) from a page handler or render closure.
That is one of the most common Vango correctness failures.
Progressive page actions
For forms that submit back to the current page route, pair setup.RouteForm with a page Action.
File-based route files may export:
1func Page(ctx vango.Ctx) *vango.VNode
2func Action(ctx vango.ActionCtx, in Input) (*vango.FormResult, error)
Rules:
page actions are route-bound POST handlers
input type should be a struct
use ctx.StdContext() for service and DB calls
business-rule validation returns vango.Invalid(...)
success redirects return vango.RedirectTo(...)
API routes
API files live under app/routes/api.
Typical signatures:
1func GET(ctx vango.Ctx) (T, error)
2func GET(ctx vango.Ctx, p Params) (T, error)
3func POST(ctx vango.Ctx, in Body) (T, error)
4func POST(ctx vango.Ctx, p Params, in Body) (T, error)
Return plain typed values when you do not need explicit status metadata. Return *vango.Response[T] when you do.
Useful helpers:
vango.OK(...)
vango.Created(...)
vango.Accepted(...)
vango.NoContent[T]()
vango.Paginated(...)
Useful HTTP error helpers:
vango.BadRequest(...)
vango.Unauthorized(...)
vango.Forbidden(...)
vango.NotFound(...)
vango.Conflict(...)
vango.UnprocessableEntity(...)
vango.InternalError(...)
Email integrations and custom HTTP boundaries
Treat email as service-layer I/O. Do not send it from render logic or session-loop lifecycle callbacks.
Provider webhooks are plain HTTP ingress, not Vango route handlers. Mount them on the HTTP boundary and continue routing ordinary app traffic through the Vango server handler.
The next major layer is form handling and auth. Continue to Forms and Auth.