Skills react-router-v7
React Router v7 best practices for data-driven routing. Use when implementing routes, loaders, actions, Form components, fetchers, navigation guards, protected routes, or URL search params. Triggers on createBrowserRouter, RouterProvider, useLoaderData, useActionData, useFetcher, NavLink, Outlet.
install
source · Clone the upstream repo
git clone https://github.com/openclaw/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/anderskev/react-router-v7" ~/.claude/skills/openclaw-skills-react-router-v7 && rm -rf "$T"
OpenClaw · Install into ~/.openclaw/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/openclaw/skills "$T" && mkdir -p ~/.openclaw/skills && cp -r "$T/skills/anderskev/react-router-v7" ~/.openclaw/skills/openclaw-skills-react-router-v7 && rm -rf "$T"
manifest:
skills/anderskev/react-router-v7/SKILL.mdsource content
React Router v7 Best Practices
Quick Reference
Router Setup (Data Mode):
import { createBrowserRouter, RouterProvider } from "react-router"; const router = createBrowserRouter([ { path: "/", Component: Root, ErrorBoundary: RootErrorBoundary, loader: rootLoader, children: [ { index: true, Component: Home }, { path: "products/:productId", Component: Product, loader: productLoader }, ], }, ]); ReactDOM.createRoot(root).render(<RouterProvider router={router} />);
Framework Mode (Vite plugin):
// routes.ts import { index, route } from "@react-router/dev/routes"; export default [ index("./home.tsx"), route("products/:pid", "./product.tsx"), ];
Route Configuration
Nested Routes with Outlets
createBrowserRouter([ { path: "/dashboard", Component: Dashboard, children: [ { index: true, Component: DashboardHome }, { path: "settings", Component: Settings }, ], }, ]); function Dashboard() { return ( <div> <h1>Dashboard</h1> <Outlet /> {/* Renders child routes */} </div> ); }
Dynamic Segments and Splats
{ path: "teams/:teamId" } // params.teamId { path: ":lang?/categories" } // Optional segment { path: "files/*" } // Splat: params["*"]
Key Decision Points
Form vs Fetcher
Use
: Creating/deleting with URL change, adding to history
Use <Form>
: Inline updates, list operations, popovers - no URL changeuseFetcher
Loader vs useEffect
Use loader: Data before render, server-side fetch, automatic revalidation Use useEffect: Client-only data, user-interaction dependent, subscriptions
Additional Documentation
- Data Loading: See references/loaders.md for loader patterns, parallel loading, search params
- Mutations: See references/actions.md for actions, Form, fetchers, validation
- Navigation: See references/navigation.md for Link, NavLink, programmatic nav
- Advanced: See references/advanced.md for error boundaries, protected routes, lazy loading
Mode Comparison
| Feature | Framework Mode | Data Mode | Declarative Mode |
|---|---|---|---|
| Setup | Vite plugin | | |
| Type Safety | Auto-generated types | Manual | Manual |
| SSR Support | Built-in | Manual | Limited |
| Use Case | Full-stack apps | SPAs with control | Simple/legacy |