Skip to content

/web-routing-react-router

Client-side routing with data APIs — loaders, actions, error boundaries, search params, nested layouts, and code splitting

shell
$ npx -y skills add agents-inc/skills --skill web-routing-react-router --agent claude-code

How 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
How auto-invocation works

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.md
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";
import
Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withagents-inc-skills

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?

Get the whole plugin, auto-invoked