Query Key Factories
The foundation of effective TanStack Query usage is well-structured query keys. For multi-tenant apps, this means including the account ID in every workspace-scoped query key.
We use query key factories that generate consistent keys:
```typescript export const projectKeys = { all: (accountId: string) => ['projects', accountId] as const, list: (accountId: string, filters?: ProjectFilters) => [...projectKeys.all(accountId), 'list', filters] as const, detail: (accountId: string, id: string) => [...projectKeys.all(accountId), 'detail', id] as const, } ```
This pattern ensures cache isolation between accounts and enables precise invalidation.
The Five Patterns
We've identified five distinct data fetching patterns for different scenarios:
**Pattern A: Simple** - Basic queries without SSR needs. Perfect for dashboard widgets and user settings.
**Pattern B: Dashboard** - Multiple parallel queries with proper loading states. Used for pages aggregating data from several sources.
**Pattern C: SEO** - Server-side prefetching with hydration. Essential for public-facing content pages.
**Pattern D: Multi-Tenant** - Queries scoped to the current workspace with account switching support.
**Pattern E: Protected Layout** - Layouts that fetch data and pass it to children, reducing waterfall requests.
Handling Account Switches
When users switch accounts, cached data from the previous account must be invalidated. But you don't want to clear everything—user preferences and global data should persist.
Our approach:
1. Include `accountId` in relevant query keys 2. On account switch, invalidate queries matching the previous account 3. Use `LoadingProvider` to show a transition state during refetch 4. Prefetch critical data for the new account
This creates smooth transitions without data leakage between workspaces.
Optimistic Updates
Optimistic updates dramatically improve perceived performance. When a user creates a project, they shouldn't wait for the server round-trip to see it appear.
Key considerations for multi-tenant optimistic updates:
- Always include the feed/account relationship in optimistic data - Roll back on error with proper user feedback - Invalidate queries after mutation to ensure consistency - Handle race conditions between optimistic data and server responses
Offline Support
TanStack Query's persistence plugins enable offline-first experiences. We use `persistQueryClient` with the following configuration:
- Persist to IndexedDB for larger storage capacity - Configure appropriate `maxAge` for different query types - Handle hydration carefully to avoid stale data issues - Implement conflict resolution for offline mutations
Mobile users especially appreciate being able to view cached data when connectivity is spotty.