Class: SolidRouterBridge
API / @xmachines/play-solid-router / SolidRouterBridge
Defined in: packages/play-solid-router/src/solid-router-bridge.ts:54
SolidJS Router integration bridge extending RouterBridgeBase
Implements RouterBridge protocol for SolidJS Router using Solid’s reactive primitives. The actor→router direction uses TC39 Signal watcher (from base class). The router→actor direction uses Solid’s createEffect for native reactivity.
Path parameters are extracted from Solid’s useParams() reactive proxy rather than
re-parsing the URL with URLPattern. This means parameterized routes work without the
URLPattern polyfill — Solid’s router has already extracted the values.
Extends
Constructors
Constructor
new SolidRouterBridge( solidNavigate, location, params, actor, routeMap): SolidRouterBridge;Defined in: packages/play-solid-router/src/solid-router-bridge.ts:75
Create a SolidJS Router bridge
CRITICAL: connect() must be called inside a Solid component where hooks are available.
Parameters
| Parameter | Type | Description |
|---|---|---|
solidNavigate | Navigator | Result of useNavigate() hook |
location | LocationLike | Result of useLocation() hook |
params | Params | Result of useParams() hook — used directly for path parameter extraction, avoiding the URLPattern polyfill requirement for parameterized routes |
actor | RoutableActor | XMachines actor instance |
routeMap | RouteMap | Bidirectional state ID ↔ path mapping |
Returns
SolidRouterBridge
Overrides
Properties
| Property | Modifier | Type | Default value | Description | Inherited from | Defined in |
|---|---|---|---|---|---|---|
actor | readonly | RoutableActor | undefined | A RoutableActor exposing currentRoute, initialRoute, and send. | RouterBridgeBase.actor | packages/play-router/src/router-bridge-base.ts:125 |
hasConnectedOnce | protected | boolean | false | - | RouterBridgeBase.hasConnectedOnce | packages/play-router/src/router-bridge-base.ts:103 |
isConnected | protected | boolean | false | - | RouterBridgeBase.isConnected | packages/play-router/src/router-bridge-base.ts:102 |
isProcessingNavigation | protected | boolean | false | Guards syncActorFromRouter against re-entrant calls triggered by the actor’s own guard redirects (router→actor send → signal fires → actor→router push → another syncActorFromRouter before the first one returns). NOT used for actor→router echo suppression — that is handled exclusively by lastSyncedPath, which is updated before navigateRouter() is called so any router callback for the same path short-circuits at the sanitized === lastSyncedPath check in syncActorFromRouter. | RouterBridgeBase.isProcessingNavigation | packages/play-router/src/router-bridge-base.ts:115 |
lastSyncedPath | protected | string | null | null | - | RouterBridgeBase.lastSyncedPath | packages/play-router/src/router-bridge-base.ts:104 |
routeMap | readonly | object | undefined | Bidirectional route map for stateId ↔ path resolution. Provide getStateIdByPath and getPathByStateId. Framework adapters typically wrap the result of createRouteMap(machine) or an equivalent. | RouterBridgeBase.routeMap | packages/play-router/src/router-bridge-base.ts:126 |
routeMap.getPathByStateId | public | string | null | undefined | undefined | - | - | packages/play-router/src/router-bridge-base.ts:128 |
routeMap.getStateIdByPath | public | string | null | undefined | undefined | - | - | packages/play-router/src/router-bridge-base.ts:127 |
routeWatcher | protected | | RouteWatcherHandle | null | null | - | RouterBridgeBase.routeWatcher | packages/play-router/src/router-bridge-base.ts:116 |
Methods
connect()
connect(): void;Defined in: packages/play-router/src/router-bridge-base.ts:152
Connect the router bridge to the Actor.
Sets up the TC39 Signal watcher for actor → router direction and starts watching router changes (framework-specific).
Ordering here is part of the bridge contract:
lastSyncedPathis seeded in the constructor fromactor.currentRoute- the actor watcher is installed before adapter router subscriptions
- initial sync then resolves deep-link vs restore using
actor.initialRoute
Adapters that need custom initial-sync behavior should override
getInitialRouterPath() rather than reordering connect() steps.
Returns
void
Inherited from
disconnect()
disconnect(): void;Defined in: packages/play-router/src/router-bridge-base.ts:248
Disconnect the router bridge from the Actor.
Stops signal watching and unregisters framework-specific router listener.
Returns
void
Inherited from
dispose()
dispose(): void;Defined in: packages/play-solid-router/src/solid-router-bridge.ts:187
Dispose the bridge (alias for disconnect).
Returns
void
Example
onCleanup(() => bridge.dispose());extractParams()
protected extractParams(pathname, stateId): Record<string, string>;Defined in: packages/play-solid-router/src/solid-router-bridge.ts:104
Extract path parameters using Solid’s pre-parsed useParams() values.
Solid’s router has already extracted all named parameters for the matched route
segment. Reading this.solidParams inside the createEffect callback that drives
syncActorFromRouter is safe — the reactive proxy always reflects the current
route at the time the effect runs.
Falls back to URLPattern-based extraction (base class) only when Solid provided
no params for this route (i.e. the route has no :param segments).
Parameters
| Parameter | Type | Description |
|---|---|---|
pathname | string | The actual URL path (unused — params already extracted by Solid) |
stateId | string | The matched state ID (unused — params already extracted by Solid) |
Returns
Record<string, string>
Normalized path parameters with undefined/empty values filtered out
Overrides
RouterBridgeBase.extractParams
extractQuery()
protected extractQuery(search): Record<string, string>;Defined in: packages/play-router/src/router-bridge-base.ts:439
Extract query parameters from URL search string.
Parameters
| Parameter | Type | Description |
|---|---|---|
search | string | URL search string (e.g., ‘?tab=security&page=1’) |
Returns
Record<string, string>
Extracted query parameters or empty object
Inherited from
getInitialRouterPath()
protected getInitialRouterPath(): string | null;Defined in: packages/play-solid-router/src/solid-router-bridge.ts:126
Get the current router pathname for initial URL -> actor sync on connect.
Returns
string | null
Overrides
RouterBridgeBase.getInitialRouterPath
getInitialRouterSearch()
protected getInitialRouterSearch(): string | undefined;Defined in: packages/play-solid-router/src/solid-router-bridge.ts:137
Return the initial URL search string for query-param forwarding on connect().
Reads this.location.search from Solid’s useLocation() reactive object —
the same source used by getInitialRouterPath(). An empty string (no query
params) returns undefined so syncActorFromRouter produces query: {}.
Returns
string | undefined
Overrides
RouterBridgeBase.getInitialRouterSearch
navigateRouter()
protected navigateRouter(path): void;Defined in: packages/play-solid-router/src/solid-router-bridge.ts:119
Navigate SolidJS Router to the given path.
Parameters
| Parameter | Type |
|---|---|
path | string |
Returns
void
Overrides
RouterBridgeBase.navigateRouter
resolveNavigationPath()
protected resolveNavigationPath(route): string | null;Defined in: packages/play-router/src/router-bridge-base.ts:424
Resolve an actor route value to a concrete URL path for navigation.
Bridges that receive raw actor.currentRoute values in navigateRouter
can call this to normalize stateIds (with or without # prefix) to paths.
Returns null when navigation is not possible:
- unknown stateId with no route map entry
- parameterized pattern (e.g.
/profile/:id) — no concrete values available - non-path string that isn’t a known stateId
Route maps may store stateIds with or without the # prefix; both forms
are tried automatically.
Parameters
| Parameter | Type | Description |
|---|---|---|
route | string | Raw actor route value (stateId, #-stateId, or concrete path) |
Returns
string | null
Concrete URL path, or null if navigation should be skipped
Inherited from
RouterBridgeBase.resolveNavigationPath
sanitizePath()
protected sanitizePath(pathname): string | null;Defined in: packages/play-router/src/router-bridge-base.ts:466
Sanitize and validate a raw URL pathname received from the router.
Applies the path-length cap (2048 chars), strips query strings and fragments that may have been included in the pathname segment, and normalises consecutive slashes.
Implementations that bypass syncActorFromRouter() (e.g. when using
framework-native reactive watchers that receive pre-parsed route objects)
MUST call this method before passing the path to any route-map lookup.
syncActorFromRouter() calls this internally, so bridges that delegate
to it do not need to call sanitizePath themselves.
Parameters
| Parameter | Type | Description |
|---|---|---|
pathname | string | Raw URL pathname from the framework router. |
Returns
string | null
Sanitized pathname, or null if the path is invalid / too long.
Inherited from
syncActorFromRouter()
protected syncActorFromRouter(pathname, search?): void;Defined in: packages/play-router/src/router-bridge-base.ts:324
Sync actor state when router location changes.
Known path: sends a play.route event to the actor with the matched
stateId, params, and query. Prevents circular updates via the
isProcessingNavigation flag.
Unknown/unmapped path: does NOT send a play.route event (actor state
is unchanged). Instead, actively corrects the browser URL by calling
navigateRouter(actor.currentRoute.get()) — keeping the URL in sync with
actor state even when the user types an invalid path into the address bar
or pushes one programmatically mid-session. lastSyncedPath is set to the
resolved concrete path before calling navigateRouter so the router’s own
callback for that navigation short-circuits the echo-suppression guard and
sends no spurious event.
Parameters
| Parameter | Type |
|---|---|
pathname | string |
search? | string |
Returns
void
Inherited from
RouterBridgeBase.syncActorFromRouter
syncRouterFromActor()
protected syncRouterFromActor(route): void;Defined in: packages/play-router/src/router-bridge-base.ts:289
Sync router location when actor route signal changes.
Calls navigateRouter() for framework-specific navigation.
Echo suppression — preventing the router’s own callback from re-driving the
actor — is handled entirely by lastSyncedPath: it is set to route before
navigateRouter() is called, so any syncActorFromRouter invocation for the
same path short-circuits at the sanitized === lastSyncedPath check and sends
no event regardless of whether the callback fires synchronously or asynchronously.
isProcessingNavigation is NOT set here — it is only used inside
syncActorFromRouter to guard against re-entrant guard-redirect loops.
Parameters
| Parameter | Type |
|---|---|
route | unknown |
Returns
void
Inherited from
RouterBridgeBase.syncRouterFromActor
unwatchRouterChanges()
protected unwatchRouterChanges(): void;Defined in: packages/play-solid-router/src/solid-router-bridge.ts:174
Stop watching SolidJS Router changes.
Calls the dispose function returned by createRoot() in watchRouterChanges(),
tearing down the reactive effect and freeing the isolated owner. This is the only
cleanup path — component unmount does NOT trigger this automatically.
Returns
void
Overrides
RouterBridgeBase.unwatchRouterChanges
watchRouterChanges()
protected watchRouterChanges(): void;Defined in: packages/play-solid-router/src/solid-router-bridge.ts:152
Subscribe to SolidJS Router location changes using createEffect.
MUST be called inside a Solid reactive owner (component or createRoot).
The effect runs inside createRoot() to give it a stable owner independent
of the calling component’s lifecycle — this prevents the effect from being
disposed if the component re-renders while the bridge should stay active.
The trade-off is that component unmount does NOT automatically clean up the
effect; disconnect() (or dispose()) MUST be called explicitly to avoid a leak.
Returns
void