E-commerce Dashboard
A full-featured admin panel using TanStack Query for server state and TanStack Table for data rendering with real-time updates.
Principle
Dashboard architecture separates data fetching from UI rendering. TanStack Query manages all server state — metrics, orders, inventory — while TanStack Table handles display logic. This eliminates the need for manual caching and pagination state.
Centralize all query keys in a factory file. This prevents key collisions and makes invalidation predictable across your entire dashboard.
Rules
- check_circleQuery Key FactoryUse hierarchical array keys: ["orders", "list", filters] for precise cache control.
- check_circleSeparate Data LayersKeep fetch functions outside components. Services folder → custom hooks → UI.
- check_circlePrefetch on HoverPrefetch linked records on hover to make navigation feel instant.
- check_circleOptimistic UIApply mutations optimistically and roll back on error for a snappy user experience.
Pattern
import { useQuery } from '@tanstack/react-query'; import { dashboardKeys } from '@/lib/query-keys'; export const useDashboardMetrics = (range: DateRange) => { return useQuery({ queryKey: dashboardKeys.metrics(range), queryFn: () => fetchMetrics(range), staleTime: 1000 * 60 * 5, // 5 minutes placeholderData: (prev) => prev, }); };
Implementation
Version Compatibility
Requires React 19+ and the latest stable versions of all dependencies shown.
In Next.js App Router, prefetch dashboard data in the server component and pass it to the client via HydrationBoundary for instant initial render.
import { HydrationBoundary, dehydrate } from '@tanstack/react-query'; import { getQueryClient } from '@/lib/get-query-client'; export default async function DashboardPage() { const qc = getQueryClient(); await qc.prefetchQuery({ queryKey: dashboardKeys.metrics('7d'), queryFn: () => fetchMetrics('7d'), }); return ( <HydrationBoundary state={dehydrate(qc)}> <DashboardClient /> </HydrationBoundary> ); }