Skip to content

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

ParameterTypeDescription
solidNavigateNavigatorResult of useNavigate() hook
locationLocationLikeResult of useLocation() hook
paramsParamsResult of useParams() hook — used directly for path parameter extraction, avoiding the URLPattern polyfill requirement for parameterized routes
actorRoutableActorXMachines actor instance
routeMapRouteMapBidirectional state ID ↔ path mapping

Returns

SolidRouterBridge

Overrides

RouterBridgeBase.constructor

Properties

PropertyModifierTypeDefault valueDescriptionInherited fromDefined in
actorreadonlyRoutableActorundefinedA RoutableActor exposing currentRoute, initialRoute, and send.RouterBridgeBase.actorpackages/play-router/src/router-bridge-base.ts:125
hasConnectedOnceprotectedbooleanfalse-RouterBridgeBase.hasConnectedOncepackages/play-router/src/router-bridge-base.ts:103
isConnectedprotectedbooleanfalse-RouterBridgeBase.isConnectedpackages/play-router/src/router-bridge-base.ts:102
isProcessingNavigationprotectedbooleanfalseGuards 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.isProcessingNavigationpackages/play-router/src/router-bridge-base.ts:115
lastSyncedPathprotectedstring | nullnull-RouterBridgeBase.lastSyncedPathpackages/play-router/src/router-bridge-base.ts:104
routeMapreadonlyobjectundefinedBidirectional route map for stateId ↔ path resolution. Provide getStateIdByPath and getPathByStateId. Framework adapters typically wrap the result of createRouteMap(machine) or an equivalent.RouterBridgeBase.routeMappackages/play-router/src/router-bridge-base.ts:126
routeMap.getPathByStateIdpublicstring | null | undefinedundefined--packages/play-router/src/router-bridge-base.ts:128
routeMap.getStateIdByPathpublicstring | null | undefinedundefined--packages/play-router/src/router-bridge-base.ts:127
routeWatcherprotected| RouteWatcherHandle | nullnull-RouterBridgeBase.routeWatcherpackages/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:

  • lastSyncedPath is seeded in the constructor from actor.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

RouterBridgeBase.connect


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

RouterBridgeBase.disconnect


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

ParameterTypeDescription
pathnamestringThe actual URL path (unused — params already extracted by Solid)
stateIdstringThe 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

ParameterTypeDescription
searchstringURL search string (e.g., ‘?tab=security&page=1’)

Returns

Record<string, string>

Extracted query parameters or empty object

Inherited from

RouterBridgeBase.extractQuery


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


protected navigateRouter(path): void;

Defined in: packages/play-solid-router/src/solid-router-bridge.ts:119

Navigate SolidJS Router to the given path.

Parameters

ParameterType
pathstring

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

ParameterTypeDescription
routestringRaw 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

ParameterTypeDescription
pathnamestringRaw URL pathname from the framework router.

Returns

string | null

Sanitized pathname, or null if the path is invalid / too long.

Inherited from

RouterBridgeBase.sanitizePath


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

ParameterType
pathnamestring
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

ParameterType
routeunknown

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

Overrides

RouterBridgeBase.watchRouterChanges