.claude/skills/tanstack-query/SKILL.md
Manages server state, API caching, and data fetching with TanStack React Query v5. Use when: Fetching API data, managing server state, polling for updates, handling mutations with cache invalidation.
npx skillsauth add kaxuna1/ecomsite tanstack-queryInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
TanStack React Query v5 is the sole data fetching solution for this codebase. All API data flows through React Query hooks (useQuery, useMutation, useQueryClient). Query keys follow ['entity-name'] or ['entity-name', filters, page] patterns. The QueryClient is configured in frontend/src/main.tsx with default settings.
// frontend/src/pages/ProductsPage.tsx:80-84
const { data: response, isLoading, isFetching } = useQuery({
queryKey: ['products', filters, currentPage],
queryFn: () => fetchProducts(filters, currentPage, 18),
keepPreviousData: true
});
// frontend/src/pages/admin/AdminProducts.tsx:171-177
const createMutation = useMutation({
mutationFn: (data: FormData) => createProduct(data),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['admin-products'] });
closeModal();
}
});
// frontend/src/context/ThemeContext.tsx:43-51
const { data: theme, isLoading, error } = useQuery<Theme, Error>({
queryKey: ['active-theme'],
queryFn: getActiveTheme,
staleTime: 5 * 60 * 1000,
gcTime: 10 * 60 * 1000,
refetchOnWindowFocus: false,
retry: 3,
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000)
});
| Concept | Usage | Example |
|---------|-------|---------|
| Query Key | Unique identifier + dependencies | ['products', filters, page] |
| staleTime | Time before data is considered stale | 5 * 60 * 1000 (5 min) |
| gcTime | Time before inactive data is garbage collected | 10 * 60 * 1000 (10 min) |
| keepPreviousData | Keep showing old data while fetching new | true for pagination |
| invalidateQueries | Refetch queries after mutations | queryClient.invalidateQueries({ queryKey: ['products'] }) |
// Wait for languages before validating route
const { data: languages = [], isLoading } = useQuery({
queryKey: ['languages'],
queryFn: () => fetchLanguages(false),
staleTime: 5 * 60 * 1000
});
// Component renders after data is ready
if (isLoading) return <LoadingScreen />;
// frontend/src/components/reviews/ReviewForm.tsx:42-46
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['reviews'] });
queryClient.invalidateQueries({ queryKey: ['products'] });
onSuccess?.();
}
For API client setup, see the typescript skill. For form state management alongside queries, see the react-hook-form skill. For global client state (non-server), see the zustand skill.
tools
Zustand lightweight state management with persistence and middleware. Use when: managing client-side state (cart, auth, UI preferences), replacing React Context with simpler API, accessing state outside React components, implementing localStorage persistence
development
Zod schema validation and TypeScript integration for runtime type safety. Use when: Validating API payloads, form inputs, environment variables, or any external data boundaries where TypeScript types alone cannot guarantee safety.
tools
Configures Vite 5.x build tool, dev server, and frontend asset optimization for the Luxia e-commerce platform. Use when: configuring builds, adding environment variables, optimizing bundle size, setting up testing, debugging HMR issues, or adding Vite plugins.
development
Enforces strict TypeScript types across frontend and backend codebases. Use when: Writing new services, DTOs, interfaces, type guards, debugging type errors, or ensuring type safety at API boundaries.