Skip to content

@xmachines/play-tanstack-react-router

Documentation / @xmachines/play-tanstack-react-router

TanStack React Router adapter for XMachines Play using the RouterBridge pattern.

Overview

@xmachines/play-tanstack-react-router connects a Play actor to TanStack Router through TanStackReactRouterBridge.

The bridge extends RouterBridgeBase from @xmachines/play-router, so adapter behavior stays consistent across frameworks:

  • Actor route signal (actor.currentRoute) drives router navigation.
  • Router history events send play.route intents back to the actor.
  • Guarded state transitions remain actor-owned (Actor Authority).

Installation

Terminal window
npm install @tanstack/react-router react
npm install @xmachines/play-tanstack-react-router @xmachines/play-router @xmachines/play-react

Current Exports

  • TanStackReactRouterBridge
  • RouteMap, createRouteMapFromTree, RouteMapping (type)
  • extractParams, extractQueryParams
  • PlayRouterProvider + PlayRouterProviderProps
  • re-exports: extractMachineRoutes, createRouteMap, RouterBridge, PlayRouteEvent

Peer dependencies:

  • @tanstack/react-router ^1.166.7
  • react ^18 || ^19
  • xstate ^5.0.0

URLPattern Support

This package uses the URLPattern API for route pattern matching via @xmachines/play-router.

URLPattern is available natively on Node.js 24+ and modern browsers (Chrome 95+, Firefox 117+, Safari 16.4+). On older environments, load a polyfill before importing this package — see @xmachines/play-router installation for details.

Quick Start

import { createRouter } from "@tanstack/react-router";
import { definePlayer } from "@xmachines/play-xstate";
import { extractMachineRoutes } from "@xmachines/play-router";
import {
TanStackReactRouterBridge,
createRouteMapFromTree,
} from "@xmachines/play-tanstack-react-router";
const routeTree = extractMachineRoutes(machine);
const routeMap = createRouteMapFromTree(routeTree);
const router = createRouter({ routeTree: tanstackRouteTree });
const actor = definePlayer({ machine, catalog })();
actor.start();
const bridge = new TanStackReactRouterBridge(router, actor, routeMap);
bridge.connect();
// later
bridge.disconnect();

React convenience wrapper

Use PlayRouterProvider when you want bridge lifecycle wiring in a component:

import { PlayRenderer } from "@xmachines/play-react";
<PlayRouterProvider
actor={actor}
router={router}
routeMap={routeMap}
renderer={(currentActor, currentRouter) => (
<PlayRenderer actor={currentActor} components={components} />
)}
/>;

API

TanStackReactRouterBridge

Primary adapter class.

class TanStackReactRouterBridge implements RouterBridge {
constructor(
router: TanStackRouterLike,
actor: AbstractActor<AnyActorLogic> & Routable,
routeMap: RouteMap,
);
connect(): void;
disconnect(): void;
}

RouteMap and createRouteMapFromTree

Map state IDs to URL paths and resolve URLs back to state IDs.

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 methods
class RouteMap extends BaseRouteMap {}
// Inherited API:
routeMap.getStateIdByPath(path: string): string | null
routeMap.getPathByStateId(stateId: string): string | null
// Factory from a machine route tree:
function createRouteMapFromTree(routeTree: RouteTree): RouteMap

getStateIdByPath returns null (not undefined) for unmatched paths.

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"); // null

PlayRouterProvider

React wrapper around TanStackReactRouterBridge.

interface PlayRouterProviderProps {
actor: AbstractActor<AnyActorLogic> & Routable & Viewable;
router: TanStackRouterLike;
routeMap: RouteMap;
renderer: (
actor: AbstractActor<AnyActorLogic> & Routable & Viewable,
router: TanStackRouterLike,
) => ReactNode;
}

Utilities and re-exports

  • extractParams, extractQueryParams
  • extractMachineRoutes, createRouteMap (re-exported from @xmachines/play-router)
  • RouterBridge, PlayRouteEvent types

Examples

  • Multi-router integration guide: docs/examples/multi-router-integration.md
  • Routing patterns guide: docs/examples/routing-patterns.md

Architecture

Bridge-first flow:

  1. RouterBridgeBase.connect() performs initial actor/router synchronization.
  2. Actor route updates call TanStack navigation (router.navigate({ to })).
  3. TanStack history updates are subscribed and translated to play.route events.
  4. Actor guards accept or reject transitions; infrastructure reflects resulting state.

This keeps routing infrastructure passive while preserving business-logic control.

Historical Note

SignalSyncedHistory and createPlayRouter are legacy migration-era APIs and are not part of the current quick-start path. Use TanStackReactRouterBridge + RouteMap for new integrations.

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-tanstack-react-router

TanStack Router adapter for XMachines Play architecture. Synchronizes browser URL with actor state through passive infrastructure.

Classes

Interfaces

Type Aliases

Variables

Functions