The TanStack Query integration: no hand-written query keys
Cache invalidation from the pipeline and TanStack Query's own cache used to be two separate systems that didn't know about each other. Here's how the integration package fixes that.
20 posts
Cache invalidation from the pipeline and TanStack Query's own cache used to be two separate systems that didn't know about each other. Here's how the integration package fixes that.
A component that logs on every render can fire dozens of network requests per second. Here's how per-level throttle, debounce and rate-limit policies fix it — including the one-word config typo that silently brings the flood right back.
Before touching config options, understand the client, the modules, and the pipeline — the three ideas everything else in api-client is built on.
Every project I ship ends up with the same auth-retry-cache logic copy-pasted and slightly broken. Here's why I finally turned that pattern into a real package.
How I built a fully prerendered, horizontally-scrolling terminal-themed portfolio with React 19 and vite-react-ssg — and the constraints that shaped every decision, from direct DOM mutation to sr-only crawler mirrors.
Replace the mouse pointer with a glowing dot-and-ring cursor in React by mutating the DOM directly on mousemove, and invert it over any background with mix-blend-mode: difference.
Add left/right swipe navigation to a React slideshow using touchstart and touchend, a distance threshold to ignore accidental taps, and simple direction detection.
Add arrow-key and Home/End navigation to a React slideshow, and learn the one guard that stops it from stealing keystrokes while a visitor is typing in a form.
A mouse wheel fires dozens of events per flick. Learn how to use a ref-based lock plus a timeout so one scroll gesture advances exactly one panel in a React slideshow.
Build a full-viewport horizontal slideshow in React where each section is a panel and navigation moves the whole track sideways with a single translateX on a ref.
A typewriter effect that starts from an empty string breaks prerendering and causes hydration mismatches. The fix: seed state with the full text, then replay the typing on the client as pure decoration.
Wire up react-hook-form with a Zod resolver, then make it accessible with aria-invalid, aria-describedby, and an aria-live region — plus a simple status state machine for submit feedback.
Tabs and carousels only render the active item, so crawlers and screen readers miss everything else. The fix: a visually-hidden sr-only block that mirrors the full dataset into the DOM.
A honeypot is a hidden form field humans never see and bots always fill. Here's how I added one to my contact form — the hidden input on the client and the silent 200 on the server.
window, document and localStorage don't exist in Node — so touching them at render time crashes a prerendered build. Here's the rule for keeping React SSG-safe, and the useIsMobile pattern that reads window only inside an effect.
A normal React + Vite app ships an empty HTML shell, which is bad for SEO. Here's how to prerender the real content at build time with vite-react-ssg — the single-page entry, the build script, and how hydration takes over.
Set up Vitest with jsdom and globals, then test three layers: a Zod schema, a React form with Testing Library, and a serverless handler by mocking the Resend constructor.
Centralize every bit of site copy — personal info, experience, skills, projects — into one typed TypeScript data file so components render from a single source of truth instead of hardcoded strings.
Pass an isActive prop down to each section so its entrance animations replay exactly when the panel scrolls into view — driven by a single current index in the parent.
Build a class-based React error boundary that catches render crashes, shows a recovery UI, and stays safe under static prerendering — no browser globals during render.