Documentation
¶
Overview ¶
Package router provides client-side routing for single-page applications built with GoWebComponents.
This package implements hash-based and history-based routing with support for:
- Multiple router instances
- Browser history integration
- Programmatic navigation
- Nested layout routes with explicit outlets
- Static node and component route registration
- Route-level chunk gates for lazy route artifacts
Basic usage with hash routing:
import (
"github.com/monstercameron/GoWebComponents/v4/html"
"github.com/monstercameron/GoWebComponents/v4/router"
"github.com/monstercameron/GoWebComponents/v4/ui"
)
func main() {
r := router.NewHashRouter()
r.Register("/", HomePage)
r.Register("/about", AboutPage)
r.Register("/contact", ContactPage)
r.Register("*", NotFoundPage)
r.Mount("#app")
}
Route components are regular components:
func HomePage(props router.Attrs) *router.Element {
goAbout := ui.UseEvent(func() {
router.Navigate("/about")
})
return html.Div(html.Props{},
html.H1(html.Props{}, html.Text("Welcome Home")),
html.Button(html.Props{OnClick: goAbout}, html.Text("Go to About")),
)
}
The package supports both hash-based routing (using URL fragments like #/about) and history-based routing (using the HTML5 History API).
Convenience accessors are also available for routed components:
nav := router.UseNavigate()
nav.Navigate("/about")
query := router.UseQuery()
searchTerm := query.Get("q")
params := router.UseParams()
userID := params.Get("id")
id, ok := params.Int("id")
revalidator := router.UseRevalidator()
revalidator.Revalidate()
layout := router.GetOutlet()
Parent layout routes opt in with router.Options{Layout: true} and render the active child route through router.GetOutlet().
Routes can also define async loaders that provide route-scoped data before rendering the final page component:
r.Register("/users/:id", UserProfile, router.Options{
Loader: func(ctx context.Context, routeCtx router.RouteContext) (router.Attrs, error) {
return router.Attrs{"userID": routeCtx.Params.Get("id")}, nil
},
})
Use RegisterLazy with RouteChunk when route code or a route-owned script must load before the route component and loader run.
Index ¶
- func BuildMetadataNode(parseRouterMetadata Metadata) *runtime.Element
- func BuildRouteService() pluginruntime.RouteService
- func DecodeQuery[T any](parseValues url.Values) (T, error)
- func EncodeQuery(parseValue any) url.Values
- func FragmentHref(parseFragment string) string
- func Href(parsePath string) string
- func OnNavigate(parseFn func(Location)) func()
- func RegisteredRoutes() []string
- type Location
- type Metadata
- type RouteContract
- func (parseC RouteContract) Href(parseParams map[string]string, parseQuery url.Values) (string, error)
- func (parseC RouteContract) HrefFor(parseParams RouteParamsProvider, parseQuery RouteQueryProvider) (string, error)
- func (parseC RouteContract) MustHref(parseParams map[string]string, parseQuery url.Values) string
- func (parseC RouteContract) MustHrefFor(parseParams RouteParamsProvider, parseQuery RouteQueryProvider) string
- func (parseC RouteContract) MustPath(parseParams map[string]string) string
- func (parseC RouteContract) MustPathFor(parseParams RouteParamsProvider) string
- func (parseC RouteContract) ParamNames() []string
- func (parseC RouteContract) Path(parseParams map[string]string) (string, error)
- func (parseC RouteContract) PathFor(parseParams RouteParamsProvider) (string, error)
- func (parseC RouteContract) Pattern() string
- type RouteParamsProvider
- type RouteQueryProvider
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildMetadataNode ¶
BuildMetadataNode renders route-managed metadata as SSR-safe head children.
The generated tags are marked so the client router can reconcile and clean up only framework-owned metadata during hydration and later navigations.
func BuildRouteService ¶
func BuildRouteService() pluginruntime.RouteService
BuildRouteService returns one native stub route service.
func DecodeQuery ¶
DecodeQuery decodes URL query values into a typed struct T using `query:"name"` tags (falling back to the lowercased field name), then validates the result with the validate package using any `validate:"..."` tags on the same struct. It is the typed-search-params path: read `?page=2&sort=desc` into a struct once, with conversion and validation, instead of scattering `q.Get("page")` + manual strconv + bounds checks across the codebase.
Supported field kinds: string, bool, the sized int/uint kinds, float32/64, and []string (for repeated params). A missing param leaves the field at its zero value — mark it `validate:"required"` to reject that. A malformed value (e.g. page=abc for an int) or an unsupported field kind returns an error; validation failures return the validate.Result (which implements error and carries per-field messages).
type ListQuery struct {
Page int `query:"page" validate:"gte=1"`
Sort string `query:"sort" validate:"omitempty,oneof=asc desc"`
Tags []string `query:"tag"`
}
q, err := router.DecodeQuery[ListQuery](values) // err is a validate.Result on bad input
func EncodeQuery ¶
EncodeQuery renders a typed struct (or a non-nil pointer to one) back into url.Values using the same `query:"name"` tags, skipping zero-valued fields so the resulting URL stays clean. It is the inverse of DecodeQuery, for building links and updating the address bar from typed state. By contract it takes a struct: a non-struct, nil pointer, or other value has no query fields and returns an empty url.Values (it never panics) — DecodeQuery is the validated counterpart, so encoding stays intentionally permissive.
func FragmentHref ¶
FragmentHref returns "#<fragment>" on non-browser builds.
func Href ¶
Href returns the path unchanged on non-browser builds (no active router mode to resolve against). The mode-aware implementation lives in the js/wasm build.
func OnNavigate ¶
func OnNavigate(parseFn func(Location)) func()
OnNavigate registers a navigation callback. On non-browser builds there is no live navigation, so it stores nothing and returns a no-op unsubscribe.
func RegisteredRoutes ¶
func RegisteredRoutes() []string
RegisteredRoutes returns a non-nil empty route list outside the browser runtime, where the active router table (and the Router type) are not available. The *Router method lives only in the js/wasm build alongside the type itself.
Types ¶
type Location ¶
type Location struct {
// Path is the current logical route path (no query string).
Path string
// Query is the encoded query string (without the leading '?').
Query string
// Params are the params captured by the matched route pattern.
Params map[string]string
}
Location is a snapshot of the active route used by the reactive UseRoute / UseLocation hooks (G6). Unlike InspectCurrentRoute (a non-reactive read), a component that calls UseRoute subscribes to navigation and re-renders when the location changes — so memoized chrome (active-nav highlight, breadcrumb) stays in sync without threading the path down as a prop.
type Metadata ¶
Metadata describes the route-owned metadata currently supported by the router.
These fields are intentionally narrow for the first SSR-aware metadata slice: title, description, and canonical URL. Broader head management remains a separate future concern.
type RouteContract ¶
type RouteContract struct {
// contains filtered or unexported fields
}
RouteContract stores a validated route pattern together with reverse-routing helpers.
The zero value is NOT valid: Path() and Href() on an uninitialized RouteContract return a "route contract is not initialized" error. Always construct one with DefineRoute (returns an error) or MustDefineRoute (panics on a bad pattern).
func DefineRoute ¶
func DefineRoute(parsePattern string) (RouteContract, error)
DefineRoute validates a route pattern and returns a reusable reverse-routing contract.
Example ¶
ExampleDefineRoute shows declaring a typed route contract, which validates the pattern up front and lets the app build type-safe hrefs for the route.
package main
import (
"github.com/monstercameron/GoWebComponents/v4/router"
)
func main() {
parseUserRoute := router.MustDefineRoute("/users/:id")
// parseUserRoute.Path(...) builds a concrete URL for the :id parameter.
_ = parseUserRoute
}
Output:
func MustDefineRoute ¶
func MustDefineRoute(parsePattern string) RouteContract
MustDefineRoute validates a route pattern and panics if it is invalid.
func (RouteContract) Href ¶
func (parseC RouteContract) Href(parseParams map[string]string, parseQuery url.Values) (string, error)
Href builds a validated navigation target for the contract from raw params and query values.
func (RouteContract) HrefFor ¶
func (parseC RouteContract) HrefFor(parseParams RouteParamsProvider, parseQuery RouteQueryProvider) (string, error)
HrefFor builds a validated navigation target from typed param and query providers.
func (RouteContract) MustHref ¶
MustHref builds a navigation target and panics if params do not satisfy the contract.
func (RouteContract) MustHrefFor ¶
func (parseC RouteContract) MustHrefFor(parseParams RouteParamsProvider, parseQuery RouteQueryProvider) string
MustHrefFor builds a navigation target from typed param and query providers and panics on validation failure.
func (RouteContract) MustPath ¶
func (parseC RouteContract) MustPath(parseParams map[string]string) string
MustPath builds a path and panics if params do not satisfy the contract.
func (RouteContract) MustPathFor ¶
func (parseC RouteContract) MustPathFor(parseParams RouteParamsProvider) string
MustPathFor builds a path from a typed param provider and panics if the contract fails validation.
func (RouteContract) ParamNames ¶
func (parseC RouteContract) ParamNames() []string
ParamNames returns the ordered param names required by the contract.
func (RouteContract) Path ¶
func (parseC RouteContract) Path(parseParams map[string]string) (string, error)
Path builds a validated path for the contract from raw param values.
func (RouteContract) PathFor ¶
func (parseC RouteContract) PathFor(parseParams RouteParamsProvider) (string, error)
PathFor builds a validated path from a typed param provider.
func (RouteContract) Pattern ¶
func (parseC RouteContract) Pattern() string
Pattern returns the normalized route pattern used by the contract.
type RouteParamsProvider ¶
RouteParamsProvider exposes typed route params for reverse routing helpers.
type RouteQueryProvider ¶
RouteQueryProvider exposes typed query values for reverse routing helpers.