isActiveRoute - greydragon888/real-router GitHub Wiki
router.isActiveRoute
1. Overview
What it does: Checks if the specified route is active. Supports hierarchical checking (parent is considered active if child is active) and exact comparison. Takes route's defaultParams into account.
When to use:
For determining active state in navigation/menus
For conditional UI rendering based on current route
For checking if user is in a specific application section
// Check current routerouter.isActiveRoute("home");// true if home is active// Check with parametersrouter.isActiveRoute("users.view",{id: "123"});// Hierarchical check (default)// If users.view is active, users is also considered activerouter.isActiveRoute("users");// true// Exact comparison (strictEquality=true)router.isActiveRoute("users",{},true);// false if users.view is active// Query params consideration (ignoreQueryParams=false)router.isActiveRoute("search",{q: "test"},false,false);
3. Parameters
name (required)
Type: string
Purpose: Route name to check (dot-notation for nested)
Allowed values: Valid route name (validated by regex)
On error: TypeError for invalid names
Value
Behavior
"home"
✅ Checks home route
"users.view"
✅ Checks nested route
""
⚠️ Warning + returns false
null, 123
❌ TypeError
params (optional)
Type: Params
Default value: {}
Purpose: Parameters to compare with active state
Validation: Must be plain object without functions, circular references, class instances
On error: TypeError for invalid structure
strictEquality (optional)
Type: boolean
Default value: false
Purpose: Require exact route name match
false: Hierarchical check (parent active if child is active)
true: Only exact name match
On error: TypeError for non-boolean values
ignoreQueryParams (optional)
Type: boolean
Default value: true
Purpose: Ignore query parameters during comparison
true: Only URL parameters (path params) are compared
false: All parameters including query are compared
On error: TypeError for non-boolean values
4. Return Value
Type: boolean
true: Route is active
false: Route is not active
Activity Logic
Situation
strictEquality=false
strictEquality=true
Exact name match
true
true
Child is active
true
false
Parent is active
false
false
Sibling is active
false
false
Router not started
false
false
5. Side Effects
Console warning: When called with empty string "" outputs console.warn
6. Possible Errors
Condition
Error
Message
name not a string
TypeError
Route name must be a string
params invalid structure
TypeError
[router.isActiveRoute] Invalid params structure
params contains function
TypeError
[router.isActiveRoute] Invalid params structure
params contains circular reference
TypeError
[router.isActiveRoute] Invalid params structure
params contains class instance
TypeError
[router.isActiveRoute] Invalid params structure
strictEquality not boolean
TypeError
[router.isActiveRoute] strictEquality must be a boolean, got {type}
ignoreQueryParams not boolean
TypeError
[router.isActiveRoute] ignoreQueryParams must be a boolean, got {type}
// Invalid route namerouter.isActiveRoute(null);// TypeError: Route name must be a string// Invalid paramsrouter.isActiveRoute("home","invalid");// TypeError: Invalid params structurerouter.isActiveRoute("home",{fn: ()=>{}});// TypeError: Invalid params structurerouter.isActiveRoute("home",{date: newDate()});// TypeError: Invalid params structure// Invalid boolean parametersrouter.isActiveRoute("home",{},1);// TypeError: strictEquality must be a booleanrouter.isActiveRoute("home",{},false,"true");// TypeError: ignoreQueryParams must be a boolean
7. Related Methods
Method
When to use
getState()
Get full current state
areStatesEqual()
Low-level state comparison
navigate()
Navigate to route
8. Behavior
Main Scenarios
Current route: true for active route
Inactive route: false for other routes
Router not started: Always false
Test Examples
// Current route is activeexpect(router.isActiveRoute("home")).toBe(true);// Inactive routeexpect(router.isActiveRoute("sign-in")).toBe(false);// strictEqualityrouter.navigate("sign-in");expect(router.isActiveRoute("home",{},true)).toBe(false);// Router not startedrouter.stop();expect(router.isActiveRoute("test",{})).toBe(false);
Hierarchical Check (strictEquality=false)
router.navigate("users.view",{id: "123"});// Parent is active if child is activeexpect(router.isActiveRoute("users")).toBe(true);// With exact match — noexpect(router.isActiveRoute("users",{},true)).toBe(false);// Sibling is not activeexpect(router.isActiveRoute("users.list")).toBe(false);// Parameters must matchexpect(router.isActiveRoute("users",{id: "123"})).toBe(true);expect(router.isActiveRoute("users",{id: "456"})).toBe(false);// Multi-level hierarchyrouter.navigate("section.view",{section: "section1",id: "123"});expect(router.isActiveRoute("section",{section: "section1"})).toBe(true);
Query Parameters
router.navigate("section.query",{section: "section1",param1: "value1",param2: "value2",param3: "value3",});// By default query params are ignoredexpect(router.isActiveRoute("section.query",{section: "section1"})).toBe(true,);// With ignoreQueryParams=false — all parameters must matchexpect(router.isActiveRoute("section.query",{section: "section1"},false,false),).toBe(false);expect(router.isActiveRoute("section.query",{section: "section1",param1: "value1",param2: "value2",param3: "value3",},false,false,),).toBe(true);
DefaultParams
// defaultParams are used in checkrouter.navigate("withDefaultParam");expect(router.isActiveRoute("withDefaultParam")).toBe(true);expect(router.isActiveRoute("withDefaultParam",{},true)).toBe(true);// In hierarchical checkgetConfig(router).defaultParams.users={filter: "active"};router.navigate("users.view",{id: "123",filter: "active"});expect(router.isActiveRoute("users")).toBe(true);// Explicit params override defaultParamsexpect(router.isActiveRoute("users",{filter: "inactive"})).toBe(false);
// Root node ("") always returns false with warningexpect(router.isActiveRoute("")).toBe(false);// console.warn: 'isActiveRoute("") called with empty string...'
Edge Cases
Empty string "": Returns false with warning
Router not started: Always false
Invalid params: TypeError for functions, circular references, class instances
Object.create() params: Rejected due to non-standard prototype
Non-enumerable properties: Ignored in params
Type coercion: Not applied — 123 !== "123", null !== "123"
undefined in params: Means "value must be undefined", not "skip check"
Guarantees
Route name validation caching (optimization ~40ns per call)
// ❌ Code that will break (method name)router.isActive("home");// ✅ Code after migrationrouter.isActiveRoute("home");// ❌ Code that will break (truthy boolean)router.isActive("users",{},1);// 1 was truthy → worked as true// ✅ Code after migrationrouter.isActiveRoute("users",{},true);// ❌ Code that will break (function in params)router.isActive("home",{onClick: ()=>{}});// ✅ Code after migrationrouter.isActiveRoute("home",{});// Remove functions from params// ❌ Code that will break (invalid name)router.isActive(null);// Returned falserouter.isActive(123);// Returned false// ✅ Code after migration// Fix code — pass stringrouter.isActiveRoute("home");
Implementation Changes
Method Rename
Master
Current
router.isActive()
router.isActiveRoute()
Reason: More explicit naming, matching the isXxx pattern for route state predicates.
New Functionality
Name validation: Regex check of route name via validateRouteName()
Params validation: Check for plain object, rejection of functions, circular references, class instances
Boolean validation: Strict type checking for strictEquality and ignoreQueryParams
Validation caching: Set<string> to skip repeated regex validation (~40ns savings)
Warning for "": Informative console.warn when empty string is passed
TypeScript: Full typing of parameters and return value
Optimizations
Aspect
Master
Current
Description
State creation
makeState() always
Minimal object { name, params, path: "" }
Avoids expensive buildPath()
Fast path
❌
✅ Route relationship check before expensive ops
Early return false for unrelated routes
Route name cache
❌
✅ validatedRouteNames Set
~40ns savings on repeated calls
Was (master)
Implementation issues in master branch:
No input validation
makeState() calls expensive buildPath() even when path is not needed
Truthy/falsy coercion for boolean parameters
No optimization for unrelated routes
Now (current)
Improvements:
Early validation of all parameters with clear messages
Minimal State object without buildPath()
Fast path: startsWith() check before expensive operations
Remove class instances from params (Date, RegExp, etc.)
Check code passing invalid route names
Migration Examples
// ❌ Was (master) — method namerouter.isActive("users");// ✅ Now — renamedrouter.isActiveRoute("users");// ❌ Was (master) — truthy instead of booleanrouter.isActive("users",{},1);// 1 as truerouter.isActive("users",{},"yes");// "yes" as true// ✅ Now — explicit booleanrouter.isActiveRoute("users",{},true);// ❌ Was (master) — falsy instead of booleanrouter.isActive("users",{},0);// 0 as falserouter.isActive("users",{},null);// null as false// ✅ Now — explicit booleanrouter.isActiveRoute("users",{},false);// ❌ Was (master) — function in paramsconstparams={id: "123",onClick: ()=>console.log("clicked"),// Worked};router.isActive("users",params);// ✅ Now — only serializable valuesconstparams={id: "123"};router.isActiveRoute("users",params);// ❌ Was (master) — Date in paramsrouter.isActive("events",{date: newDate()});// Worked// ✅ Now — string instead of Daterouter.isActiveRoute("events",{date: "2024-01-01"});
Summary
Category
Status
Breaking Changes
🔴 CRITICAL (method rename)
New validation
✅ name, params, boolean parameters
Optimizations
✅ Fast path, caching, minimal State
TypeScript
✅ Full typing
Warnings
✅ console.warn for ""
Maximum severity: 🔴 CRITICAL
Main change: Method renamed from isActive to isActiveRoute.
Global search and replace required: router.isActive( → router.isActiveRoute(
Additional changes:
Strict validation of all parameters
TypeError instead of silent false for invalid input
Boolean parameters no longer accept truthy/falsy values