/web-routing-react-router
Client-side routing with data APIs — loaders, actions, error boundaries, search params, nested layouts, and code splitting
$ npx -y skills add agents-inc/skills --skill web-routing-react-router --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/web-routing-react-router
Context preview
The summary Claude sees to decide when to auto-load this skill.
Client-side routing with data APIs — loaders, actions, error boundaries, search params, nested layouts, and code splitting
SKILL.md
web-routing-react-router.SKILL.mdname: web-routing-react-router
description: Client-side routing with data APIs — loaders, actions, error boundaries, search params, nested layouts, and code splitting
React Router Patterns
> **Quick Guide:** React Router v7 has three modes: Declarative (`<BrowserRouter>`), Data (`createBrowserRouter`), and Framework (Vite plugin). This skill covers **Data Mode** — the sweet spot for SPAs needing loaders, actions, and pending states without a full framework. All imports come from `"react-router"` (the `react-router-dom` package is removed). `defer()` and `json()` are removed in v7 — return plain objects from loaders. Form method values are now uppercase (`"POST"`, not `"post"`).
---
<critical_requirements>
CRITICAL: Before Using This Skill
> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)
**(You MUST use `createBrowserRouter` + `<RouterProvider>` for Data Mode — NEVER use `<BrowserRouter>` with `<Routes>` if you need loaders, actions, or fetchers)**
**(You MUST import from `"react-router"` — the `react-router-dom` package is removed in v7. All exports, including `RouterProvider` and `createBrowserRouter`, come from `"react-router"`)**
**(You MUST return plain objects from loaders — `json()` and `defer()` are removed in v7. Return `{ data }` directly or use `Response.json()`)**
**(You MUST use `throw redirect()` in loaders and shared helpers to short-circuit execution — `return redirect()` also works but does not stop execution in helper function call stacks)**
**(You MUST use `errorElement` or `ErrorBoundary` on routes — unhandled loader/action errors crash the entire router)**
</critical_requirements>
---
**Auto-detection:** React Router, createBrowserRouter, RouterProvider, useLoaderData, useActionData, useNavigation, useSearchParams, useFetcher, useRouteError, useParams, useNavigate, Outlet, NavLink, Form, loader, action, errorElement, ErrorBoundary, redirect, isRouteErrorResponse, route.lazy, useOutletContext, shouldRevalidate, useRevalidator
**When to use:**
- Building React SPAs that need data loading, form actions, or pending states
- Apps requiring nested layouts with shared UI (sidebars, headers)
- Route-level error boundaries and not-found handling
- URL search param state management
- Code splitting at the route level
- Non-navigating mutations (fetchers for inline forms, buttons)
**Key patterns covered:**
- Data Mode setup with `createBrowserRouter` and `RouterProvider`
- Route loaders and actions for data fetching and mutations
- Nested layouts with `<Outlet />` and `useOutletContext`
- Type-safe navigation with `Link`, `NavLink`, `useNavigate`, `redirect`
- Error handling with `errorElement`, `useRouteError`, `isRouteErrorResponse`
- Search params with `useSearchParams`
- Non-navigating mutations with `useFetcher`
- Code splitting with `route.lazy`
- Navigation state with `useNavigation`
- Protected routes and auth guard patterns
**When NOT to use:**
- Simple apps with 1-2 pages and no data loading (Declarative Mode with `<BrowserRouter>` is sufficient)
- Full-stack SSR apps (use Framework Mode or an SSR framework instead)
- Static sites without client-side navigation
---
Examples
- [Core Setup & Route Config](examples/core.md) -- createBrowserRouter, RouterProvider, route objects, basic loaders
- [Data Loading & Actions](examples/data-loading.md) -- loaders, actions, Form, useFetcher, revalidation
- [Navigation & Search Params](examples/navigation.md) -- Link, NavLink, useNavigate, redirect, useSearchParams
- [Error Handling & Code Splitting](examples/error-handling.md) -- errorElement, useRouteError, route.lazy, pending UI
- [Layouts & Auth Guards](examples/layouts.md) -- Outlet, useOutletContext, protected routes, nested layouts
For quick API reference (hooks, components, route options), see [reference.md](reference.md).
---
<philosophy>
Philosophy
React Router v7 treats the router as a data layer, not just a URL matcher. Routes define what data to load (`loader`), what mutations to handle (`action`), and what errors to catch (`errorElement`) — all before the component renders. This moves data orchestration out of components and into the route tree, eliminating loading waterfalls and duplicated error handling.
**Core principles:**
- **Routes own their data** — Loaders fetch before render, actions handle mutations. Components receive data, they do not fetch it.
- **URL is the source of truth** — Search params, path params, and navigation state all live in the URL. No hidden state.
- **Errors bubble up** — Like React error boundaries, `errorElement` catches errors at the nearest route. Unhandled errors bubble to the parent.
- **Revalidation is automatic** — After a successful action, all active loaders re-run. No manual cache invalidation needed. (In v7, loaders skip revalidation after action errors unless `shouldRevalidate` opts in.)
- **Fetchers are for mutations without navigation** — `useFetcher` handles inline forms, buttons, and background saves without changing the URL.
**When to use Data Mode:**
- SPAs with data loading needs and client-side routing
- Apps where you want route-level loaders/actions but control your own bundling
- Projects not ready for Framework Mode but outgrowing Declarative Mode
**When NOT to use:**
- If you only need URL matching and `<Link>` — Declarative Mode is simpler
- If you want SSR, streaming, or file-based routing — Framework Mode or an SSR framework is better
- If your app has no data loading — the overhead of Data Mode is not justified
</philosophy>
---
<patterns>
Core Patterns
Pattern 1: Data Mode Setup
Define routes as objects with `createBrowserRouter`. Pass the router to `<RouterProvider>`. This is the entry point for all Data Mode features.
import { createBrowserRouter, RouterProvider } from "react-router";
import { RootLayout } from "./layouts/root-layout";
importRead more
name: web-routing-react-router description: Client-side routing with data APIs — loaders, actions, error boundaries, search params, nested layouts, and code splitting
React Router Patterns
> **Quick Guide:** React Router v7 has three modes: Declarative (`<BrowserRouter>`), Data (`createBrowserRouter`), and Framework (Vite plugin). This skill covers **Data Mode** — the sweet spot for SPAs needing loaders, actions, and pending states without a full framework. All imports come from `"react-router"` (the `react-router-dom` package is removed). `defer()` and `json()` are removed in v7 — return plain objects from loaders. Form method values are now uppercase (`"POST"`, not `"post"`).
---
<critical_requirements>
CRITICAL: Before Using This Skill
> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)
**(You MUST use `createBrowserRouter` + `<RouterProvider>` for Data Mode — NEVER use `<BrowserRouter>` with `<Routes>` if you need loaders, actions, or fetchers)**
**(You MUST import from `"react-router"` — the `react-router-dom` package is removed in v7. All exports, including `RouterProvider` and `createBrowserRouter`, come from `"react-router"`)**
**(You MUST return plain objects from loaders — `json()` and `defer()` are removed in v7. Return `{ data }` directly or use `Response.json()`)**
**(You MUST use `throw redirect()` in loaders and shared helpers to short-circuit execution — `return redirect()` also works but does not stop execution in helper function call stacks)**
**(You MUST use `errorElement` or `ErrorBoundary` on routes — unhandled loader/action errors crash the entire router)**
</critical_requirements>
---
**Auto-detection:** React Router, createBrowserRouter, RouterProvider, useLoaderData, useActionData, useNavigation, useSearchParams, useFetcher, useRouteError, useParams, useNavigate, Outlet, NavLink, Form, loader, action, errorElement, ErrorBoundary, redirect, isRouteErrorResponse, route.lazy, useOutletContext, shouldRevalidate, useRevalidator
**When to use:**
- Building React SPAs that need data loading, form actions, or pending states
- Apps requiring nested layouts with shared UI (sidebars, headers)
- Route-level error boundaries and not-found handling
- URL search param state management
- Code splitting at the route level
- Non-navigating mutations (fetchers for inline forms, buttons)
**Key patterns covered:**
- Data Mode setup with `createBrowserRouter` and `RouterProvider`
- Route loaders and actions for data fetching and mutations
- Nested layouts with `<Outlet />` and `useOutletContext`
- Type-safe navigation with `Link`, `NavLink`, `useNavigate`, `redirect`
- Error handling with `errorElement`, `useRouteError`, `isRouteErrorResponse`
- Search params with `useSearchParams`
- Non-navigating mutations with `useFetcher`
- Code splitting with `route.lazy`
- Navigation state with `useNavigation`
- Protected routes and auth guard patterns
**When NOT to use:**
- Simple apps with 1-2 pages and no data loading (Declarative Mode with `<BrowserRouter>` is sufficient)
- Full-stack SSR apps (use Framework Mode or an SSR framework instead)
- Static sites without client-side navigation
---
Examples
- [Core Setup & Route Config](examples/core.md) -- createBrowserRouter, RouterProvider, route objects, basic loaders
- [Data Loading & Actions](examples/data-loading.md) -- loaders, actions, Form, useFetcher, revalidation
- [Navigation & Search Params](examples/navigation.md) -- Link, NavLink, useNavigate, redirect, useSearchParams
- [Error Handling & Code Splitting](examples/error-handling.md) -- errorElement, useRouteError, route.lazy, pending UI
- [Layouts & Auth Guards](examples/layouts.md) -- Outlet, useOutletContext, protected routes, nested layouts
For quick API reference (hooks, components, route options), see [reference.md](reference.md).
---
<philosophy>
Philosophy
React Router v7 treats the router as a data layer, not just a URL matcher. Routes define what data to load (`loader`), what mutations to handle (`action`), and what errors to catch (`errorElement`) — all before the component renders. This moves data orchestration out of components and into the route tree, eliminating loading waterfalls and duplicated error handling.
**Core principles:**
- **Routes own their data** — Loaders fetch before render, actions handle mutations. Components receive data, they do not fetch it.
- **URL is the source of truth** — Search params, path params, and navigation state all live in the URL. No hidden state.
- **Errors bubble up** — Like React error boundaries, `errorElement` catches errors at the nearest route. Unhandled errors bubble to the parent.
- **Revalidation is automatic** — After a successful action, all active loaders re-run. No manual cache invalidation needed. (In v7, loaders skip revalidation after action errors unless `shouldRevalidate` opts in.)
- **Fetchers are for mutations without navigation** — `useFetcher` handles inline forms, buttons, and background saves without changing the URL.
**When to use Data Mode:**
- SPAs with data loading needs and client-side routing
- Apps where you want route-level loaders/actions but control your own bundling
- Projects not ready for Framework Mode but outgrowing Declarative Mode
**When NOT to use:**
- If you only need URL matching and `<Link>` — Declarative Mode is simpler
- If you want SSR, streaming, or file-based routing — Framework Mode or an SSR framework is better
- If your app has no data loading — the overhead of Data Mode is not justified
</philosophy>
---
<patterns>
Core Patterns
Pattern 1: Data Mode Setup
Define routes as objects with `createBrowserRouter`. Pass the router to `<RouterProvider>`. This is the entry point for all Data Mode features.
import { createBrowserRouter, RouterProvider } from "react-router";
import { RootLayout } from "./layouts/root-layout";
importShowing the first part of this file.
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
Other skills on agents-inc-skills.
- /ai-infrastructure-huggingface-inference
Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation, audio transcription, translation, summarization, and Inference Endpoints
Open skill - /ai-infrastructure-litellm
LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production deployment
Open skill - /ai-infrastructure-modal
Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns
Open skill - /ai-infrastructure-ollama
Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and OpenAI-compatible endpoint
Open skill - /ai-infrastructure-replicate
Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training
Open skill - /ai-infrastructure-together-ai
Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation, fine-tuning, and OpenAI-compatible endpoints
Open skill

