Skip to main content

Data Fetching

TanStack Start provides powerful data fetching capabilities that integrate seamlessly with TanStack Router. Learn how to fetch data efficiently using server functions, loaders, and various loading strategies.

Overview

Data fetching in TanStack Start can happen:
  • On the server during SSR
  • On the client after hydration
  • In route loaders before navigation
  • In components on-demand

Using Route Loaders

Route loaders are the primary way to fetch data for a route:

Data Loading Strategies

Parallel Loading

Load multiple resources simultaneously:

Deferred Loading

Defer slow data to improve perceived performance:

Waterfall Loading

Load data that depends on previous results:

Conditional Loading

Load data based on conditions:

Fetching in Components

Fetch data on-demand within components:

Caching Strategies

Client-Side Caching

Implement caching with React Query:

Static Data Caching

Cache server function results statically:

Preloading Data

Preload data before navigation:
Preload options:
  • preload="intent" - Preload on hover or focus
  • preload="render" - Preload when link renders
  • preload={false} - Disable preloading

Error Handling

Handling Errors in Loaders

Error Boundaries

Revalidation

Invalidate Route Data

Revalidate on Actions

Optimistic Updates

Best Practices

  1. Fetch Early
    • Use route loaders to fetch data before rendering
    • Leverage preloading for anticipated navigations
  2. Parallel When Possible
    • Load independent data in parallel with Promise.all()
    • Only use waterfalls when data dependencies exist
  3. Defer Slow Operations
    • Use deferred loading for non-critical data
    • Show meaningful loading states
  4. Handle Errors Gracefully
    • Provide error boundaries for each route
    • Give users clear error messages and recovery options
  5. Cache Strategically
    • Cache frequently accessed, rarely changing data
    • Use stale-while-revalidate patterns
    • Consider static generation for truly static data
  6. Optimize Payload Size
    • Only fetch the data you need
    • Use database projections/selections
    • Consider pagination for large datasets
  7. Type Everything
    • Define types for all data structures
    • Use validators to ensure runtime type safety
    • Leverage TypeScript’s inference

Next Steps