|
| 1 | +# Router Analytics Plugin |
| 2 | + |
| 3 | +The **Router Analytics** plugin tracks page-to-page transitions and predicts likely next routes. It can also emit **prefetch hints** for the most probable next pages, so your app can warm up data/assets. |
| 4 | + |
| 5 | +> This is a **built‑in plugin**. It doesn’t change your routing— it observes navigations and learns probabilities. |
| 6 | +
|
| 7 | +## Features |
| 8 | + |
| 9 | +* Records transitions between normalized routes (e.g. `/posts` → `/settings`). |
| 10 | +* Exposes **transition probabilities** and **top‑N predictions**. |
| 11 | +* Optional **prefetch hints** over a netcode channel (browser / Wasm builds). |
| 12 | +* Pluggable route normalization. |
| 13 | + |
| 14 | +## Quick Start |
| 15 | + |
| 16 | +Register the plugin at boot: |
| 17 | + |
| 18 | +```go |
| 19 | +import ( |
| 20 | + core "github.com/rfwlab/rfw/v1/core" |
| 21 | + routeranalytics "github.com/rfwlab/rfw/v1/plugins/routeranalytics" |
| 22 | +) |
| 23 | + |
| 24 | +func main() { |
| 25 | + core.RegisterPlugin(routeranalytics.New(routeranalytics.Options{ |
| 26 | + // optional: customize behavior |
| 27 | + // PrefetchLimit: 3, // number of next routes to hint |
| 28 | + // PrefetchThreshold: 0.25, // drop hints below this probability |
| 29 | + // Channel: "RouterPrefetch", // netcode channel name |
| 30 | + // Normalize: routeranalytics.NormalizePath, // default normalization |
| 31 | + })) |
| 32 | +} |
| 33 | +``` |
| 34 | + |
| 35 | +The plugin automatically hooks into the app router and learns from each navigation. |
| 36 | + |
| 37 | +## Example (predict next routes) |
| 38 | + |
| 39 | +```go |
| 40 | +// Get ordered probabilities for what users do next from "/posts" |
| 41 | +probs := routeranalytics.TransitionProbabilities("/posts") |
| 42 | +for _, p := range probs { |
| 43 | + // p.To, p.Count, p.Probability |
| 44 | +} |
| 45 | + |
| 46 | +// Ask for the top 2 most likely next routes |
| 47 | +top2 := routeranalytics.MostLikelyNext("/posts", 2) |
| 48 | +``` |
| 49 | + |
| 50 | +If `PrefetchLimit` > 0, each navigation will enqueue prefetch hints for predicted routes with probability ≥ `PrefetchThreshold` (browser/Wasm builds only). |
| 51 | + |
| 52 | +## How It Works |
| 53 | + |
| 54 | +* **Normalization** (default): trims whitespace, removes `?query` and `#hash`, and ensures a **leading slash**. |
| 55 | +* **Learning**: each navigation updates counters for `from → to` and totals per `from`. |
| 56 | +* **Probabilities**: computed as `count(from→to) / total(from)` and returned **sorted** by probability (then alphabetically by `to`). |
| 57 | +* **Prefetch**: in Wasm builds, predicted routes are sent once over a netcode client on the configured channel. |
| 58 | + |
| 59 | +## API Reference |
| 60 | + |
| 61 | +### Types |
| 62 | + |
| 63 | +```go |
| 64 | +type Options struct { |
| 65 | + Normalize func(string) string // normalize a path before tracking |
| 66 | + PrefetchLimit int // number of routes to prefetch (<=0 disables) |
| 67 | + PrefetchThreshold float64 // drop hints below this probability (<=0 → 0.2) |
| 68 | + Channel string // netcode channel (default "RouterPrefetch") |
| 69 | +} |
| 70 | + |
| 71 | +type TransitionProbability struct { |
| 72 | + From string |
| 73 | + To string |
| 74 | + Count int |
| 75 | + Probability float64 |
| 76 | +} |
| 77 | +``` |
| 78 | + |
| 79 | +### Constructors & Plugin hooks |
| 80 | + |
| 81 | +```go |
| 82 | +func New(opts Options) *Plugin |
| 83 | +func (p *Plugin) Name() string // "routeranalytics" |
| 84 | +func (p *Plugin) Build(json.RawMessage) error // no-op |
| 85 | +func (p *Plugin) Install(a *core.App) // attaches to router |
| 86 | +``` |
| 87 | + |
| 88 | +### Instance methods |
| 89 | + |
| 90 | +```go |
| 91 | +func (p *Plugin) TransitionProbabilities(from string) []TransitionProbability |
| 92 | +func (p *Plugin) MostLikelyNext(from string, limit int) []TransitionProbability |
| 93 | +func (p *Plugin) Reset() |
| 94 | +``` |
| 95 | + |
| 96 | +### Package helpers (use the latest installed instance) |
| 97 | + |
| 98 | +```go |
| 99 | +func TransitionProbabilities(from string) []TransitionProbability |
| 100 | +func MostLikelyNext(from string, limit int) []TransitionProbability |
| 101 | +func Reset() |
| 102 | +``` |
| 103 | + |
| 104 | +### Utilities |
| 105 | + |
| 106 | +```go |
| 107 | +// Default normalization: trim, strip query/hash, ensure leading slash. |
| 108 | +func NormalizePath(path string) string |
| 109 | +``` |
| 110 | + |
| 111 | +## Defaults |
| 112 | + |
| 113 | +* `Normalize`: `NormalizePath` |
| 114 | +* `PrefetchLimit`: `3` (set `< 0` to disable, `0` → `3`) |
| 115 | +* `PrefetchThreshold`: `0.2` if `<= 0` |
| 116 | +* `Channel`: `"RouterPrefetch"` |
0 commit comments