All skills
remix-run avatar

/react-router-declarative-mode

@7c69689
by Remixremix-run/agent-skills136 stars
4

Build React applications using React Router's declarative mode with BrowserRouter. Use when configuring routes with JSX, navigating with Link/NavLink, or reading URL params and search params without data loaders or actions.

Use this Skill: https://skilld.dev/gh/remix-run/agent-skills/react-router-declarative-mode

This session only. Nothing lands on disk.

referencesrouting.md

≈1.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Routing

In declarative mode, routes are configured using JSX with <Routes> and <Route> components wrapped in a <BrowserRouter>.

Basic Setup

import { BrowserRouter, Routes, Route } from "react-router";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
        <Route path="contact" element={<Contact />} />
      </Routes>
    </BrowserRouter>
  );
}

Route Component Props

Prop Purpose Example
path URL pattern to match path="users/:id"
element Component to render element={<User />}
index Default child route (no path) <Route index element={...} />
children Nested routes <Route path="dashboard">...</Route>

Nested Routes

Child routes are nested inside parent routes. Use <Outlet /> in the parent to render the matched child:

import { Routes, Route, Outlet } from "react-router";

function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      <nav>
        <Link to="settings">Settings</Link>
        <Link to="profile">Profile</Link>
      </nav>
      <Outlet />
    </div>
  );
}

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="dashboard" element={<Dashboard />}>
          <Route index element={<DashboardHome />} />
          <Route path="settings" element={<Settings />} />
          <Route path="profile" element={<Profile />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

This creates:

  • /dashboard → <Dashboard> with <DashboardHome /> in the outlet
  • /dashboard/settings → <Dashboard> with <Settings /> in the outlet
  • /dashboard/profile → <Dashboard> with <Profile /> in the outlet

Layout Routes

Routes without a path act as layout wrappers:

<Routes>
  <Route element={<MarketingLayout />}>
    <Route path="/" element={<Home />} />
    <Route path="about" element={<About />} />
    <Route path="contact" element={<Contact />} />
  </Route>
  <Route element={<AppLayout />}>
    <Route path="dashboard" element={<Dashboard />} />
    <Route path="settings" element={<Settings />} />
  </Route>
</Routes>

All routes under a layout route render inside that layout's <Outlet />.

Index Routes

Index routes render at the parent's URL (the "default" child):

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="dashboard" element={<Dashboard />}>
    <Route index element={<DashboardHome />} />
    <Route path="settings" element={<Settings />} />
  </Route>
</Routes>
  • / → <Home />
  • /dashboard → <Dashboard> with <DashboardHome /> in outlet
  • /dashboard/settings → <Dashboard> with <Settings /> in outlet

Index routes cannot have children.

Route Prefixes

A Route with path but without element adds a path prefix to its children without introducing a layout:

<Routes>
  {/* /projects/... without a shared layout */}
  <Route path="projects">
    <Route index element={<ProjectsHome />} />
    <Route path=":projectId" element={<Project />} />
    <Route path=":projectId/edit" element={<EditProject />} />
  </Route>
</Routes>

This is useful when routes share a path prefix but don't need a shared layout component.

Dynamic Segments

Segments starting with : are dynamic and captured as params:

<Route path="users/:userId" element={<User />} />
<Route path="posts/:postId/comments/:commentId" element={<Comment />} />

Access params with useParams():

import { useParams } from "react-router";

function User() {
  const { userId } = useParams();
  return <h1>User {userId}</h1>;
}

Optional Segments

Add ? to make a segment optional:

<Route path=":lang?/products" element={<Products />} />
// matches /products and /en/products

<Route path="users/:userId/edit?" element={<User />} />
// matches /users/123 and /users/123/edit

Splats (Catch-All)

Match any remaining path with *:

<Route path="files/*" element={<FileViewer />} />
import { useParams } from "react-router";

function FileViewer() {
  const { "*": filePath } = useParams();
  // filePath = "docs/intro.md" for /files/docs/intro.md
  return <div>Viewing: {filePath}</div>;
}

404 Catch-All

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="about" element={<About />} />
  <Route path="*" element={<NotFound />} />
</Routes>

Anti-Pattern: Flat Routes

// ❌ DON'T: Flat structure when routes share layout
function App() {
  return (
    <Routes>
      <Route path="dashboard" element={<Dashboard />} />
      <Route path="dashboard/settings" element={<DashboardSettings />} />
      <Route path="dashboard/profile" element={<DashboardProfile />} />
    </Routes>
  );
}

// ✅ DO: Use nested routes with shared layout
function App() {
  return (
    <Routes>
      <Route path="dashboard" element={<DashboardLayout />}>
        <Route index element={<Dashboard />} />
        <Route path="settings" element={<DashboardSettings />} />
        <Route path="profile" element={<DashboardProfile />} />
      </Route>
    </Routes>
  );
}

Nested routes:

  • Share layout code via <Outlet />
  • Reduce code duplication
  • Make it clear which routes are related
  • Enable layout-level state persistence

Linking Basics

Use <Link> for navigation between routes:

import { Link } from "react-router";

function Nav() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/users/123">User 123</Link>
    </nav>
  );
}

See navigation.md for full details on navigation patterns.

See Also

Source: SKILL.md on GitHub

1 warning15d5 checks · Risk SAFE
  • Gen Agent Trust Hub15d

    The skill provides comprehensive documentation and best practices for using React Router's declarative mode. It covers route configuration, navigation components, and hooks for reading URL values. No security issues or malicious patterns were detected.

  • Socket15d

    No alerts

  • Snyk15d

    Risk: LOW · No issues

  • Runlayer7mo

    4/4 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 7c69689. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last week.

Steadyupdated 8 months ago

README badge

README badge for remix-run/agent-skills/react-router-declarative-mode