Skip to content

Documentation: Add TanStack Router Integration Guide #2298

@justin808

Description

@justin808

Summary

This issue requests documentation for integrating TanStack Router with React on Rails for server-side rendering applications. A working demo and comprehensive guide have been created in the react_on_rails-demos repository (PR #104).

Context

TanStack Router is a popular type-safe, file-based routing library for React. Integrating it with React on Rails SSR requires specific patterns that should be documented.

Key Integration Patterns Discovered

1. Router Factory with Conditional History

export function createRouter(opts?: { initialUrl?: string }) {
  const isServer = typeof window === 'undefined';

  // Use memory history on server, browser history on client
  const history = isServer
    ? createMemoryHistory({
        initialEntries: [opts?.initialUrl || '/'],
      })
    : undefined;

  return createTanStackRouter({
    routeTree,
    ...(history ? { history } : {}),
  });
}

2. Separate Client/Server Components

Server Component:

  • Uses required initialUrl prop
  • Creates new router instance each render
  • Calls router.load() synchronously (Promise is voided)

Client Component:

  • Uses React.useState(() => createRouter({ initialUrl })) to create router once
  • Prevents re-creation during hydration
  • Passes initialUrl for consistency with server

3. Rails Controller Pattern

def index
  @props = {
    initialUrl: request.fullpath  # Critical for SSR route matching
  }
end

4. Rails Routes Must Match Client Routes

Rails.application.routes.draw do
  root "my_app#index"
  get "about", to: "my_app#index"
  get "users", to: "my_app#index"
  get "users/:userId", to: "my_app#index"
  # All TanStack routes point to same controller action
end

Important SSR Limitations

  1. Async loaders are NOT supported with React on Rails' renderToString
  2. Data should be passed via props from Rails controller
  3. router.load() returns a Promise but route matching is synchronous

Recommendations for Data Fetching

  1. Preferred: Pass data from Rails controller via props
  2. Alternative: Client-side fetching with loading states
  3. Advanced: Use renderFunction for async SSR support

Rspack/Webpack Configuration

The TanStack Router plugin should be added to the client config:

if (config.assets_bundler === 'rspack') {
  const { TanStackRouterRspack } = require('@tanstack/router-plugin/rspack');
  clientConfig.plugins.push(
    TanStackRouterRspack({
      target: 'react',
      autoCodeSplitting: true,
      routesDirectory: path.resolve(__dirname, '../../app/javascript/src/routes'),
      generatedRouteTree: path.resolve(__dirname, '../../app/javascript/src/routeTree.gen.ts'),
    })
  );
}

Requested Documentation Updates

  1. Add a new guide: "Integrating TanStack Router with React on Rails"
  2. Update SSR documentation to mention router library considerations
  3. Add examples showing the client/server component pattern for routers
  4. Document the initialUrl prop pattern for SSR

Related

Checklist

  • Add TanStack Router integration guide to docs
  • Update SSR documentation with router considerations
  • Add code examples for client/server component pattern
  • Document common pitfalls (async loaders, hydration mismatches)

Metadata

Metadata

Assignees

Labels

P2Backlog priority

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions