getTree - greydragon888/real-router GitHub Wiki
getPluginApi().getTree
Method for plugin authors
1. Overview
- What it does: Returns the current route tree — the hierarchical structure of all registered routes
- When to use:
- Inspect the registered route hierarchy (route names, paths, parameters)
- Plugin infrastructure that needs to analyze the route structure
- Debugging and introspection of route definitions
- Building route-aware UI (breadcrumbs, navigation menus)
- Access:
getPluginApi(router).getTree()— this is a plugin API method, not a router method
2. Signature
import { getPluginApi } from "@real-router/core/api";
import type { RouteTree } from "route-tree";
// RouteTree is also re-exported from @real-router/core for convenience:
import type { RouteTree } from "@real-router/core";
const pluginApi = getPluginApi(router);
pluginApi.getTree(): RouteTree
Note:
getTree()returns a properly typedRouteTree. The type is re-exported from@real-router/corefor convenience — no need to import from internalroute-treepackage.
Return Value
Returns the root RouteTree node of the route hierarchy:
interface RouteTree {
readonly name: string; // Route segment name (e.g., "users")
readonly path: string; // Route path pattern (e.g., "/users/:id")
readonly absolute: boolean; // Whether path uses absolute matching (~)
readonly children: ReadonlyMap<string, RouteTree>; // Child routes (O(1) lookup by name)
readonly paramMeta: ParamMeta; // Parameter metadata from path
readonly parent: RouteTree | null; // Parent node (null for root)
readonly nonAbsoluteChildren: readonly RouteTree[]; // Children without absolute paths
readonly fullName: string; // Pre-computed full name (e.g., "users.profile")
readonly staticPath: string | null; // Pre-computed static path (if no params)
readonly paramTypeMap: Readonly<Record<string, "url" | "query">>; // Param type map
}
3. Possible Errors
The getTree() method does not throw errors. It always returns the current route tree.
Note: getTree() does NOT check disposed state. It can be called even after router.dispose().
4. Related Methods
| Method | Description |
|---|---|
getRoutesApi().get() |
Get a single route definition by name |
getRoutesApi().has() |
Check if a route exists |
buildState |
Validate route and get segment metadata |
matchPath |
Match a URL path against the tree |
getRouteUtils |
Create cached RouteUtils from tree |
5. Behavior
Tree Structure
The returned tree is a hierarchical structure where each node represents a route segment:
import { getPluginApi, getRoutesApi } from "@real-router/core/api";
const routes = getRoutesApi(router);
const pluginApi = getPluginApi(router);
routes.add({ name: "users", path: "/users" });
routes.add({ name: "users.profile", path: "/:id" });
routes.add({ name: "users.settings", path: "/settings" });
const tree = pluginApi.getTree();
// tree.name === "" (root)
// tree.children.get("users") → RouteTree for "users"
// tree.children.get("users").children.get("profile") → RouteTree for "users.profile"
Traversing the Tree
Walk the tree to inspect all routes:
import { getPluginApi } from "@real-router/core/api";
const pluginApi = getPluginApi(router);
const tree = pluginApi.getTree();
function printRoutes(node: RouteTree, indent = 0) {
if (node.fullName) {
console.log(" ".repeat(indent) + node.fullName + " → " + node.path);
}
for (const child of node.children.values()) {
printRoutes(child, indent + 2);
}
}
printRoutes(tree);
// Output:
// users → /users
// profile → /:id
// settings → /settings
Immutability
The returned tree is deeply frozen — all nodes and their properties are read-only. Do not attempt to mutate the tree:
const tree = pluginApi.getTree();
tree.name = "modified"; // TypeError: Cannot assign to read only property 'name'
Tree Updates
The tree is rebuilt when routes are added, updated, or removed:
import { getPluginApi, getRoutesApi } from "@real-router/core/api";
const pluginApi = getPluginApi(router);
const routes = getRoutesApi(router);
const tree1 = pluginApi.getTree();
routes.add({ name: "admin", path: "/admin" });
const tree2 = pluginApi.getTree();
// tree1 !== tree2 (new tree instance after route change)
// tree2.children.has("admin") === true
Root Node
The returned tree is the root node (empty name, no parent):
const tree = pluginApi.getTree();
tree.name === ""; // Root has empty name
tree.parent === null; // Root has no parent
tree.fullName === ""; // Root has empty fullName
6. Plugin Example
import { getPluginApi, getRoutesApi } from "@real-router/core/api";
import type { PluginFactory, RouteTree } from "@real-router/core";
const routeInspectorPlugin: PluginFactory = (router) => {
const pluginApi = getPluginApi(router);
function findRoute(name: string): RouteTree | undefined {
const tree = pluginApi.getTree();
const segments = name.split(".");
let current = tree;
for (const segment of segments) {
const child = current.children.get(segment);
if (!child) return undefined;
current = child;
}
return current;
}
function getRouteDepth(name: string): number {
const route = findRoute(name);
return route ? name.split(".").length : -1;
}
return {
onStart() {
const tree = pluginApi.getTree();
console.log("Routes registered:", tree.children.size);
},
};
};
7. Migration
The getTree() method moved from the router instance to the plugin API:
// Before
const tree = router.getTree();
// After
import { getPluginApi } from "@real-router/core/api";
const pluginApi = getPluginApi(router);
const tree = pluginApi.getTree();