router

package
v4.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 5, 2026 License: MIT Imports: 9 Imported by: 0

README

GWC | Router Library

GoWebComponents (GWC)

High-Level Overview

The router library provides client-side routing, route matching, navigation, and loader orchestration for GWC single-page apps.

Public APIs

github.com/monstercameron/GoWebComponents/router (package router)
  • Functions: AllowNavigation, BlockNavigation, Bool, Current, DefineRoute, Delete, Encode, Get, GetCurrentPath, GetCurrentRouterPath, GetOutlet, GetRoute, GetRouter, GoGetRoute, GoRegisterRoute, Has, Href, HrefFor, HydrateMount, HydrateMountElement, InspectCurrentRoute, Int, IsLoading, Loading, MetadataNode, Mount, MountElement, MustDefineRoute, MustHref, MustHrefFor, MustPath, MustPathFor, Navigate, NavigateReplace, NewHashRouter, NewHistoryRouter, ParamNames, Path, PathFor, Pattern, PreserveReturnTo, ReadReturnTo, RedirectNavigation, Register, RegisterRoute, Replace, ReplaceAll, Revalidate, RouteWithElement, Set, UseNavigate, UseParams, UseQuery, UseRevalidator, UseRouteData, UseSearchParams, Values
  • Types: AsyncGuardFunc, AsyncLeaveGuardFunc, Attrs, Component, Element, GuardDecision, GuardFunc, GuardResult, LeaveGuardFunc, LoaderFunc, Metadata, Navigator, Options, Params, Query, Revalidator, RouteContext, RouteContract, RouteInspection, RouteLoaderInspection, RouteParamsProvider, RouteQueryProvider, RouteRedirectInspection, RouteStackInspection, Router, RouterOptions, SearchParams
  • Variables: none
  • Constants: ReturnToParam

Subfiles And Purpose

  • browser_router_test.go - Tests for browser_router behavior
  • browser_test_helpers_wasm_test.go - Tests for browser_test_helpers_wasm behavior
  • contracts.go - Core implementation for contracts
  • contracts_additional_test.go - Tests for contracts_additional behavior
  • contracts_test.go - Tests for contracts behavior
  • doc.go - Package-level Go documentation
  • example_test.go - Tests for example behavior
  • metadata.go - Core implementation for metadata
  • metadata_test.go - Tests for metadata behavior
  • README.md - Folder-level documentation
  • router.go - Core implementation for router
  • router_benchmark_test.go - Tests for router_benchmark behavior
  • router_test.go - Tests for router behavior

File Map

router/
|-- browser_router_test.go
|-- browser_test_helpers_wasm_test.go
|-- contracts.go
|-- contracts_additional_test.go
|-- contracts_test.go
|-- doc.go
|-- example_test.go
|-- metadata.go
|-- metadata_test.go
|-- README.md
|-- router.go
|-- router_benchmark_test.go
\-- router_test.go

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

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildMetadataNode

func BuildMetadataNode(parseRouterMetadata Metadata) *runtime.Element

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

func DecodeQuery[T any](parseValues url.Values) (T, error)

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

func EncodeQuery(parseValue any) url.Values

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

func FragmentHref(parseFragment string) string

FragmentHref returns "#<fragment>" on non-browser builds.

func Href

func Href(parsePath string) string

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.

func UseLocation

func UseLocation() Location

UseLocation is an alias for UseRoute (native stub).

func UseRoute

func UseRoute() Location

UseRoute is a non-reactive empty snapshot outside the browser runtime, where there is no live navigation to subscribe to. The reactive implementation lives in the js/wasm build.

func (Location) Param

func (parseLoc Location) Param(parseKey string) string

Param returns the captured route param for key, or "" if absent.

type Metadata

type Metadata struct {
	Title        string
	Description  string
	CanonicalURL string
}

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
}

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

func (parseC RouteContract) MustHref(parseParams map[string]string, parseQuery url.Values) string

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

type RouteParamsProvider interface {
	RouteParams() map[string]string
}

RouteParamsProvider exposes typed route params for reverse routing helpers.

type RouteQueryProvider

type RouteQueryProvider interface {
	RouteQuery() url.Values
}

RouteQueryProvider exposes typed query values for reverse routing helpers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL