Guard type

Guard is a stubbed route guard for non-WASM builds.

Type Definition:

func(map[string]string) bool

Route struct

Route describes a route mapping in stub builds.

Fields:

  • Path (string)
  • Component (func() core.Component)
  • Guards ([]Guard)
  • Children ([]Route)

RegisteredRoute struct

RegisteredRoute describes a registered route in stub builds.

Fields:

  • Template (string)
  • Path (string)
  • Params ([]string)
  • Children ([]RegisteredRoute)

Reset function

Reset is a no-op in stub builds.

Show/Hide Function Body
{}

RegisterRoute function

RegisterRoute is a no-op in stub builds.

Parameters:

  • r Route

References:

Show/Hide Function Body
{}

RegisteredRoutes function

RegisteredRoutes returns nil in stub builds.

Returns:

  • []RegisteredRoute
Show/Hide Function Body
{ return nil }

ExposeNavigate function

ExposeNavigate is a no-op in stub builds.

Show/Hide Function Body
{}

InitRouter function

InitRouter is a no-op in stub builds.

Show/Hide Function Body
{}

trailingComponent struct

Methods:

Render


Returns:
  • string

Show/Hide Method Body
{ return "" }

Mount


Show/Hide Method Body
{}

Unmount


Show/Hide Method Body
{}

OnMount


Show/Hide Method Body
{}

OnUnmount


Show/Hide Method Body
{}

GetName


Returns:
  • string

Show/Hide Method Body
{ return "trailing" }

GetID


Returns:
  • string

Show/Hide Method Body
{ return "" }

SetSlots


Parameters:
  • map[string]any

Show/Hide Method Body
{}

TestNavigateTrailingSlash function

Parameters:

  • t *testing.T
Show/Hide Function Body
{
	Reset()
	RegisterRoute(Route{Path: "/trail", Component: func() core.Component { return &trailingComponent{} }})
	Navigate("/trail/")
	if _, ok := currentComponent.(*trailingComponent); !ok {
		t.Fatalf("expected trailingComponent with trailing slash, got %T", currentComponent)
	}
}

TestNavigateTrailingSlashNotFound function

Parameters:

  • t *testing.T
Show/Hide Function Body
{
	Reset()
	RegisterRoute(Route{Path: "/trail", Component: func() core.Component { return &trailingComponent{} }})
	called := false
	NotFoundCallback = func(p string) { called = true }
	Navigate("/trail/extra")
	if !called {
		t.Fatalf("expected NotFoundCallback for extra path, got none")
	}
	NotFoundCallback = nil
}

Guard type

Guard is a function that determines whether navigation to a route is

permitted based on the provided parameters.

Type Definition:

func(map[string]string) bool

Route struct

Route describes a routing rule that maps a path to a component and optional

guards or child routes.

Fields:

  • Path (string)
  • Component (func() core.Component)
  • Guards ([]Guard)
  • Children ([]Route)

route struct

Fields:

  • pattern (string)
  • regex (*regexp.Regexp)
  • paramNames ([]string)
  • component (core.Component)
  • loader (func() core.Component)
  • children ([]route)
  • guards ([]Guard)

RegisteredRoute struct

RegisteredRoute describes a registered route in a navigable tree form.

Fields:

  • Template (string) - json:"template"
  • Path (string) - json:"path"
  • Params ([]string) - json:"params"
  • Children ([]RegisteredRoute) - json:"children"

Reset function

Reset clears the router's registered routes and current component.

It is primarily intended for use in tests to ensure a clean state.

Show/Hide Function Body
{
	routes = nil
	currentComponent = nil
}

RegisterRoute function

RegisterRoute adds a new Route to the router's configuration.

Parameters:

  • r Route

References:

Show/Hide Function Body
{
	routes = append(routes, buildRoute(r))
}

buildRoute function

Parameters:

  • r Route

Returns:

  • route

References:

Show/Hide Function Body
{
	segments := strings.Split(strings.Trim(r.Path, "/"), "/")
	regexParts := make([]string, len(segments))
	paramNames := []string{}

	for i, segment := range segments {
		if strings.HasPrefix(segment, ":") {
			name := strings.TrimPrefix(segment, ":")
			paramNames = append(paramNames, name)
			regexParts[i] = "([^/]+)"
		} else {
			regexParts[i] = regexp.QuoteMeta(segment)
		}
	}

	pathRegex := strings.Join(regexParts, "/")
	suffix := "/?$"
	if len(r.Children) > 0 {
		suffix = "(?:/|$)"
	}
	if pathRegex == "" {
		suffix = "$"
	}
	pattern := "^/" + pathRegex + suffix
	rt := route{
		pattern:    r.Path,
		regex:      regexp.MustCompile(pattern),
		paramNames: paramNames,
		loader:     r.Component,
		guards:     r.Guards,
	}

	for _, child := range r.Children {
		rt.children = append(rt.children, buildRoute(child))
	}

	return rt
}

RegisteredRoutes function

RegisteredRoutes returns the registered routes including nested children and

resolved full paths. The data can be used for tooling and diagnostics.

Returns:

  • []RegisteredRoute
Show/Hide Function Body
{
	out := make([]RegisteredRoute, 0, len(routes))
	for i := range routes {
		out = append(out, snapshotRoute(&routes[i], ""))
	}
	return out
}

snapshotRoute function

Parameters:

  • r *route
  • parent string

Returns:

  • RegisteredRoute

References:

Show/Hide Function Body
{
	params := make([]string, len(r.paramNames))
	copy(params, r.paramNames)
	full := resolveRoutePath(parent, r.pattern)
	children := make([]RegisteredRoute, len(r.children))
	for i := range r.children {
		children[i] = snapshotRoute(&r.children[i], full)
	}
	return RegisteredRoute{
		Template: r.pattern,
		Path:     full,
		Params:   params,
		Children: children,
	}
}

resolveRoutePath function

Parameters:

  • parent string
  • path string

Returns:

  • string
Show/Hide Function Body
{
	if path == "" {
		if parent == "" {
			return "/"
		}
		return parent
	}
	if strings.HasPrefix(path, "/") {
		return path
	}
	trimmed := strings.TrimPrefix(path, "/")
	if parent == "" || parent == "/" {
		return "/" + trimmed
	}
	if strings.HasSuffix(parent, "/") {
		return parent + trimmed
	}
	return parent + "/" + trimmed
}

routeParamReceiver interface

Methods:

SetRouteParams


Parameters:
  • map[string]string

matchRoute function

Parameters:

  • routes []route
  • path string

Returns:

  • *route
  • []Guard
  • map[string]string
Show/Hide Function Body
{
	for i := range routes {
		r := &routes[i]
		if matches := r.regex.FindStringSubmatch(path); matches != nil {
			params := map[string]string{}
			for i, name := range r.paramNames {
				if i+1 < len(matches) {
					params[name] = matches[i+1]
				}
			}
			if child, guards, childParams := matchRoute(r.children, path); child != nil {
				for k, v := range params {
					childParams[k] = v
				}
				return child, append(r.guards, guards...), childParams
			}
			return r, r.guards, params
		}
	}
	return nil, nil, nil
}

CanNavigate function

CanNavigate reports whether the specified path matches a registered route.

Parameters:

  • fullPath string

Returns:

  • bool
Show/Hide Function Body
{
	path := fullPath
	if idx := strings.Index(fullPath, "?"); idx != -1 {
		path = fullPath[:idx]
	}
	r, _, _ := matchRoute(routes, path)
	return r != nil
}

ExposeNavigate function

ExposeNavigate makes the Navigate function accessible from JavaScript and

automatically routes internal anchor clicks.

Show/Hide Function Body
{
	exposeNavigateOnce.Do(func() {
		js.ExposeFunc("goNavigate", func(this js.Value, args []js.Value) any {
			path := args[0].String()
			Navigate(path)
			return nil
		})

		events.On("click", js.Document(), func(evt js.Value) {
			link := evt.Get("target").Call("closest", "a[href]")
			if !link.Truthy() {
				return
			}
			if t := link.Get("target").String(); t != "" && t != "_self" {
				return
			}
			if link.Get("origin").String() != js.Location().Get("origin").String() {
				return
			}
			path := link.Get("pathname").String() + link.Get("search").String()
			if CanNavigate(path) {
				evt.Call("preventDefault")
				Navigate(path)
			}
		})
	})
}

InitRouter function

InitRouter initializes the router and begins listening for navigation

events.

Show/Hide Function Body
{
	ch := events.Listen("popstate", js.Window())
	go func() {
		for range ch {
			path := js.Location().Get("pathname").String() + js.Location().Get("search").String()
			Navigate(path)
		}
	}()

	currentPath := js.Location().Get("pathname").String() + js.Location().Get("search").String()
	Navigate(currentPath)
}

testComponent struct

Methods:

Render


Returns:
  • string

Show/Hide Method Body
{ return "" }

Mount


Show/Hide Method Body
{}

Unmount


Show/Hide Method Body
{}

OnMount


Show/Hide Method Body
{}

OnUnmount


Show/Hide Method Body
{}

GetName


Returns:
  • string

Show/Hide Method Body
{ return "test" }

GetID


Returns:
  • string

Show/Hide Method Body
{ return "" }

SetSlots


Parameters:
  • map[string]any

Show/Hide Method Body
{}

Render


Returns:
  • string

Show/Hide Method Body
{ return "" }

Mount


Show/Hide Method Body
{}

Unmount


Show/Hide Method Body
{}

OnMount


Show/Hide Method Body
{}

OnUnmount


Show/Hide Method Body
{}

GetName


Returns:
  • string

Show/Hide Method Body
{ return "test" }

GetID


Returns:
  • string

Show/Hide Method Body
{ return "" }

SetSlots


Parameters:
  • map[string]any

Show/Hide Method Body
{}

SetRouteParams


Parameters:
  • p map[string]string

Show/Hide Method Body
{ c.params = p }

TestCanNavigate function

Parameters:

  • t *testing.T
Show/Hide Function Body
{
	Reset()
	RegisterRoute(Route{Path: "/can", Component: func() core.Component { return &testComponent{} }})
	if !CanNavigate("/can") {
		t.Fatalf("expected true for registered route")
	}
	if !CanNavigate("/can?foo=bar") {
		t.Fatalf("expected true for registered route with query")
	}
	if CanNavigate("/missing") {
		t.Fatalf("expected false for unregistered route")
	}
}

testComponent struct

testComponent implements core.Component and routeParamReceiver for testing.

Fields:

  • params (map[string]string)

Methods:

Render


Returns:
  • string

Show/Hide Method Body
{ return "" }

Mount


Show/Hide Method Body
{}

Unmount


Show/Hide Method Body
{}

OnMount


Show/Hide Method Body
{}

OnUnmount


Show/Hide Method Body
{}

GetName


Returns:
  • string

Show/Hide Method Body
{ return "test" }

GetID


Returns:
  • string

Show/Hide Method Body
{ return "" }

SetSlots


Parameters:
  • map[string]any

Show/Hide Method Body
{}

Render


Returns:
  • string

Show/Hide Method Body
{ return "" }

Mount


Show/Hide Method Body
{}

Unmount


Show/Hide Method Body
{}

OnMount


Show/Hide Method Body
{}

OnUnmount


Show/Hide Method Body
{}

GetName


Returns:
  • string

Show/Hide Method Body
{ return "test" }

GetID


Returns:
  • string

Show/Hide Method Body
{ return "" }

SetSlots


Parameters:
  • map[string]any

Show/Hide Method Body
{}

SetRouteParams


Parameters:
  • p map[string]string

Show/Hide Method Body
{ c.params = p }

TestNavigateQueryParams function

Parameters:

  • t *testing.T
Show/Hide Function Body
{
	Reset()
	RegisterRoute(Route{Path: "/query", Component: func() core.Component { return &testComponent{} }})
	Navigate("/query?key=value")
	tc, ok := currentComponent.(*testComponent)
	if !ok {
		t.Fatalf("expected testComponent, got %T", currentComponent)
	}
	if tc.params["key"] != "value" {
		t.Fatalf("expected query param 'key=value', got %v", tc.params)
	}
}

TestNavigateNotFound function

Parameters:

  • t *testing.T
Show/Hide Function Body
{
	Reset()
	called := false
	NotFoundCallback = func(p string) { called = true }
	Navigate("/missing")
	if !called {
		t.Fatalf("expected NotFoundCallback to be called")
	}
	NotFoundCallback = nil
}

routeComponent struct

Methods:

Render


Returns:
  • string

Show/Hide Method Body
{ return "" }

Mount


Show/Hide Method Body
{}

Unmount


Show/Hide Method Body
{}

OnMount


Show/Hide Method Body
{}

OnUnmount


Show/Hide Method Body
{}

GetName


Returns:
  • string

Show/Hide Method Body
{ return "route" }

GetID


Returns:
  • string

Show/Hide Method Body
{ return "route" }

SetSlots


Parameters:
  • map[string]any

Show/Hide Method Body
{}

TestRegisteredRoutes function

Parameters:

  • t *testing.T
Show/Hide Function Body
{
	Reset()
	RegisterRoute(Route{Path: "/static", Component: func() core.Component { return routeComponent{} }})
	RegisterRoute(Route{
		Path:      "/users",
		Component: func() core.Component { return routeComponent{} },
		Children: []Route{
			{
				Path:      ":id",
				Component: func() core.Component { return routeComponent{} },
			},
			{
				Path:      ":id/profile",
				Component: func() core.Component { return routeComponent{} },
			},
		},
	})

	defs := RegisteredRoutes()
	if len(defs) != 2 {
		t.Fatalf("expected 2 top level routes, got %d", len(defs))
	}
	if defs[0].Path != "/static" || len(defs[0].Params) != 0 {
		t.Fatalf("unexpected static route: %+v", defs[0])
	}

	users := defs[1]
	if users.Path != "/users" {
		t.Fatalf("expected /users path, got %s", users.Path)
	}
	if len(users.Children) != 2 {
		t.Fatalf("expected two children, got %d", len(users.Children))
	}
	child := users.Children[0]
	if child.Path != "/users/:id" {
		t.Fatalf("expected /users/:id full path, got %s", child.Path)
	}
	if len(child.Params) != 1 || child.Params[0] != "id" {
		t.Fatalf("expected id param, got %+v", child.Params)
	}
	profile := users.Children[1]
	if profile.Path != "/users/:id/profile" {
		t.Fatalf("expected /users/:id/profile path, got %s", profile.Path)
	}
}

reloadComponent struct

Methods:

Render


Returns:
  • string

Show/Hide Method Body
{ return "" }

Mount


Show/Hide Method Body
{}

Unmount


Show/Hide Method Body
{}

OnMount


Show/Hide Method Body
{}

OnUnmount


Show/Hide Method Body
{}

GetName


Returns:
  • string

Show/Hide Method Body
{ return "reload" }

GetID


Returns:
  • string

Show/Hide Method Body
{ return "" }

SetSlots


Parameters:
  • map[string]any

Show/Hide Method Body
{}

TestNavigateReloadsRouteEachTime function

Parameters:

  • t *testing.T
Show/Hide Function Body
{
	Reset()
	count := 0
	RegisterRoute(Route{Path: "/reload", Component: func() core.Component {
		count++
		return &reloadComponent{}
	}})
	Navigate("/reload")
	Navigate("/reload")
	if count != 2 {
		t.Fatalf("expected loader called twice, got %d", count)
	}
}

github.com/rfwlab/rfw/v1/core import

Import example:

import "github.com/rfwlab/rfw/v1/core"

testing import

Import example:

import "testing"

github.com/rfwlab/rfw/v1/core import

Import example:

import "github.com/rfwlab/rfw/v1/core"

net/url import

Import example:

import "net/url"

regexp import

Import example:

import "regexp"

strings import

Import example:

import "strings"

sync import

Import example:

import "sync"

github.com/rfwlab/rfw/v1/core import

Import example:

import "github.com/rfwlab/rfw/v1/core"

github.com/rfwlab/rfw/v1/dom import

Import example:

import "github.com/rfwlab/rfw/v1/dom"

github.com/rfwlab/rfw/v1/events import

Import example:

import "github.com/rfwlab/rfw/v1/events"

Imported as:

events

github.com/rfwlab/rfw/v1/js import

Import example:

import "github.com/rfwlab/rfw/v1/js"

Imported as:

js

testing import

Import example:

import "testing"

github.com/rfwlab/rfw/v1/core import

Import example:

import "github.com/rfwlab/rfw/v1/core"

testing import

Import example:

import "testing"

github.com/rfwlab/rfw/v1/core import

Import example:

import "github.com/rfwlab/rfw/v1/core"

testing import

Import example:

import "testing"

github.com/rfwlab/rfw/v1/core import

Import example:

import "github.com/rfwlab/rfw/v1/core"

testing import

Import example:

import "testing"

github.com/rfwlab/rfw/v1/core import

Import example:

import "github.com/rfwlab/rfw/v1/core"