@xmachines/play-react-router
Documentation / @xmachines/play-react-router
React Router v7 adapter for XMachines Play using RouterBridgeBase.
Overview
@xmachines/play-react-router connects react-router v7 data routers to Play actors.
The package provides:
ReactRouterBridgefor direct adapter controlPlayRouterProviderfor React lifecycle wiringRouteMaputilities for state ID <-> URL path resolution
Internally, ReactRouterBridge extends RouterBridgeBase from @xmachines/play-router, so behavior matches other bridge adapters in the monorepo.
Installation
npm install react react-routernpm install @xmachines/play-react-router @xmachines/play-router @xmachines/play-reactCurrent Exports
ReactRouterBridgePlayRouterProvider+PlayRouterProviderPropsRouteMapcreateRouteMapFromTree- type re-exports:
RouterBridge,PlayRouteEvent
Peer dependencies:
react^18 || ^19react-router^7.0.0
Use @xmachines/play-react for framework-native rendering (PlayRenderer).
Quick Start
import { createBrowserRouter } from "react-router";import { definePlayer } from "@xmachines/play-xstate";import { extractMachineRoutes } from "@xmachines/play-router";import { ReactRouterBridge, createRouteMapFromTree } from "@xmachines/play-react-router";
const router = createBrowserRouter(routes);const actor = definePlayer({ machine, catalog })();actor.start();
const routeTree = extractMachineRoutes(machine);const routeMap = createRouteMapFromTree(routeTree);
const bridge = new ReactRouterBridge(router, actor, routeMap);bridge.connect();
// laterbridge.disconnect();ReactRouterBridge requires the data-router API (createBrowserRouter).
BrowserRouter is not supported because it does not expose subscribe/navigate APIs needed by the bridge.
API
ReactRouterBridge
class ReactRouterBridge extends RouterBridgeBase { constructor( router: ReturnType<typeof createBrowserRouter>, actor: AbstractActor<AnyActorLogic> & Routable, routeMap: RouteMap, ); connect(): void; disconnect(): void;}Responsibilities:
- Watch React Router location updates and sync actor via
play.route - Observe actor route changes and navigate router when state changes
- Handle initial URL sync on cold load/deep links
PlayRouterProvider
React wrapper that creates/connects/disconnects ReactRouterBridge in useEffect:
interface PlayRouterProviderProps { actor: AbstractActor<AnyActorLogic> & Routable & Viewable; router: ReturnType<typeof createBrowserRouter>; routeMap: RouteMap; renderer: ( actor: AbstractActor<AnyActorLogic> & Routable & Viewable, router: ReturnType<typeof createBrowserRouter>, ) => ReactNode;}RouteMap and createRouteMapFromTree
RouteMap extends BaseRouteMap from @xmachines/play-router, inheriting bucket-indexed
bidirectional route matching. No routing logic lives in the adapter itself.
// RouteMap is a thin subclass of BaseRouteMap — no extra methodsclass RouteMap extends BaseRouteMap {}
// Inherited API:routeMap.getStateIdByPath(path: string): string | nullrouteMap.getPathByStateId(stateId: string): string | null
// Factory from a machine route tree:function createRouteMapFromTree(routeTree: RouteTree): RouteMapgetStateIdByPath returns null (not undefined) for unmatched paths.
Construct directly when you have static mappings:
import { RouteMap } from "@xmachines/play-react-router";
const routeMap = new RouteMap([ { stateId: "home", path: "/" }, { stateId: "profile", path: "/profile/:userId" }, { stateId: "settings", path: "/settings/:section?" },]);
routeMap.getStateIdByPath("/profile/123"); // "profile"routeMap.getPathByStateId("home"); // "/"routeMap.getStateIdByPath("/unknown"); // nullOr build from a machine’s route tree:
import { extractMachineRoutes } from "@xmachines/play-router";import { createRouteMapFromTree } from "@xmachines/play-react-router";
const routeMap = createRouteMapFromTree(extractMachineRoutes(machine));Examples
- Routing patterns guide:
docs/examples/routing-patterns.md - Multi-router integration guide:
docs/examples/multi-router-integration.md
Architecture
Bridge-first adapter flow:
- Build route map from
extractMachineRoutes(machine). - Connect
ReactRouterBridge(orPlayRouterProvider). - Router navigation emits path updates to actor via
play.routeevents. - Actor transitions (and guards) determine valid state.
- Actor route signal updates router URL when accepted.
This keeps infrastructure passive and preserves Actor Authority.
Related Packages
License
Copyright (c) 2016 Mikael Karon. All rights reserved.
This work is licensed under the terms of the MIT license.
For a copy, see https://opensource.org/licenses/MIT.
@xmachines/play-react-router
React Router v7 adapter for XMachines Play architecture. Synchronizes browser URL with actor state using createBrowserRouter data API.