docs/oss/building-features/tanstack-router.md
TanStack Router is a fully type-safe React router with built-in data loading, search param validation, and first-class TypeScript support. It's a strong choice when you want end-to-end type safety from your route definitions through to your components and search params.
React on Rails Pro supports TanStack Router SSR via react-on-rails-pro/tanstack-router.
This helper creates a render-function that handles both server-side rendering and client hydration/navigation.
TanStack Router SSR requires React on Rails Pro with the Node Renderer and
rendering_returns_promises = true in your Pro configuration. The async Node Renderer
uses TanStack Router's public router.load() API for reliable, maintainable SSR.
Client-side-only TanStack Router (without SSR) works with the open-source package - no special integration is needed since it's just a standard React app.
react-on-rails-pro/tanstack-routerrendering_returns_promises = trueThis guide intentionally avoids an ExecJS SSR path.
Synchronous SSR with TanStack Router pushes React on Rails toward private TanStack Router internals.
The Pro-only async path keeps the integration on TanStack Router's public router.load(),
router.dehydrate(), and router.hydrate() APIs, which is a much better long-term maintenance boundary.
pnpm add @tanstack/react-router
Create a render-function with createTanStackRouterRenderFunction and register it with React on Rails:
import ReactOnRails from 'react-on-rails-pro';
import { createTanStackRouterRenderFunction } from 'react-on-rails-pro/tanstack-router';
import {
RouterProvider,
createBrowserHistory,
createMemoryHistory,
createRouter,
} from '@tanstack/react-router';
import { routeTree } from '../routes/routeTree.gen';
const TanStackApp = createTanStackRouterRenderFunction(
{
createRouter: () => createRouter({ routeTree }),
// AppWrapper: ({ children }) => <MyProviders>{children}</MyProviders>, // optional
},
{
RouterProvider,
createMemoryHistory,
createBrowserHistory,
},
);
ReactOnRails.register({ TanStackApp });
Then render it from Rails:
<%= react_component("TanStackApp", props: { currentUserId: current_user&.id }, prerender: true) %>
On the server, the helper returns a server render hash:
{
renderedHtml: ReactElement,
clientProps: {
__tanstackRouterDehydratedState: { ... }
}
}
React on Rails then:
renderedHtml into HTML.clientProps into the client hydration payload generated by react_component.When using this helper with prerender: true, pass props: as a Ruby Hash or a JSON object string.
If you pass a JSON string that parses to a non-object value (like an array), React on Rails raises an error.
Ensure your React on Rails Pro initializer includes:
ReactOnRailsPro.configure do |config|
# TanStack Router SSR requires the Pro Node Renderer async path.
config.rendering_returns_promises = true
end
@tanstack/react-router versions: >=1.139.0 <2.0.0react-on-rails-pro up to date when upgrading @tanstack/react-router.react_on_rails_pro/spec/dummy/config/routes.rbreact_on_rails_pro/spec/dummy/app/views/tanstack_router/index.html.erbreact_on_rails_pro/spec/dummy/client/app/ror-auto-load-components/TanStackRouterAppAsync.jsxreact_on_rails_pro/spec/dummy/spec/system/integration_spec.rb