ai-infrastructure-hugg…
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation,…
SWR data fetching patterns — keys and fetchers, isLoading vs isValidating, revalidation strategy, useSWRMutation, useSWRInfinite, conditional fetching
$ npx -y skills add agents-inc/skills --skill web-data-fetching-swr --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/web-data-fetching-swrContext preview
The summary Claude sees to decide when to auto-load this skill.
SWR data fetching patterns — keys and fetchers, isLoading vs isValidating, revalidation strategy, useSWRMutation, useSWRInfinite, conditional fetching
name: web-data-fetching-swr description: SWR data fetching patterns — keys and fetchers, isLoading vs isValidating, revalidation strategy, useSWRMutation, useSWRInfinite, conditional fetching
> **Quick Guide:** SWR renders the cached value immediately and revalidates behind it, so the cache > key is the whole identity of a request and an unstable key is the single most expensive mistake > here. `isLoading` covers the first fetch only and `isValidating` covers every fetch, which is why > using the second as a spinner hides the data SWR exists to show. Reads are `useSWR`, writes are > `useSWRMutation`, and a `null` key is how a request is skipped without breaking the rules of hooks.
**Detailed Resources:**
---
page's key and signals the end by returning `null`. Pattern 7.
non-null; see [examples/suspense.md](examples/suspense.md). Everything else here still applies.
---
<critical_requirements>
**Give each request a key that is stable across renders — a string, or an array of primitives.** The key is the cache identity and the dependency: an object or array literal is a new reference every render, so SWR sees a new key, fetches again, re-renders, and repeats.
**Throw from the fetcher on a non-OK response.** SWR's error state is driven by a rejected promise, so a fetcher that returns `res.json()` unconditionally hands the error body over as `data` and no error branch ever runs.
**Branch on `isLoading` for the first fetch and `isValidating` for a refresh in progress.** `isLoading` is true only when there is no data yet, which is exactly when a skeleton is right; `isValidating` is true during background revalidation, when there is data on screen to keep.
**Reach for `useSWRMutation` for anything that writes.** `useSWR` fires on mount, so a POST written as a `useSWR` fetcher sends itself as soon as the component renders.
</critical_requirements>
---
**Auto-detection:** `useSWR`, `useSWRMutation`, `useSWRInfinite`, `useSWRImmutable`, `SWRConfig`, `useSWRConfig`, `mutate`, `trigger`, `isValidating`, `revalidateOnFocus`, `dedupingInterval`, `keepPreviousData`, `fallbackData`, `optimisticData`, `rollbackOnError`, `populateCache`, `preload`, `swr/mutation`, `swr/infinite`, `swr/immutable`
**Applies to:**
**Handled elsewhere:**
whole responses under a key
---
<philosophy>
The name is the algorithm: return what is cached, revalidate behind it, re-render if the answer changed. A component therefore has data at nearly every moment of its life, and the interesting states are not "loading or loaded" but "is this being checked" and "is this out of date".
Everything else follows. The key is a global identity, so two components asking for the same key share one request and one cache entry with no coordination between them. Revalidation is triggered by events the user causes — refocusing the tab, reconnecting — rather than by timers, because those are the moments the data on screen is most likely to be stale.
</philosophy>
---
<patterns>
interface FetchError extends Error {
info: unknown;
status: number;
}
const fetcher = async <T>(url: string): Promise<T> => {
const response = await fetch(url);
if (!response.ok) {
const error = new Error("Fetch failed") as FetchError;
error.info = await response.json().catch(() => null);
error.status = response.status;
throw error;
}
return response.json();
};Attaching `status` is what lets a component tell a 404 from a 500, and lets a retry policy decline to retry either. Define the fetcher at module scope — one created inside a component is a new reference on every render.
Full code: [examples/core.md](examples/core.md) — client-based and multi-argument fetchers
---
// data: undefined, isLoading: true, isValidating: true — first fetch // data: T, isLoading: false, isValidating: fal
The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?
Repo: agents-inc/skills
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation,…
LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production…
Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns
Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and…
Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training
Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation,…