{"filename":"react-router-v7.mdc","content":"---\ndescription: React Router v7 rules for framework mode, data routers, loaders, actions, route modules, and progressive enhancement\nglobs: [\"app/routes/**/*\", \"src/routes/**/*\", \"routes/**/*\", \"react-router.config.*\", \"vite.config.*\", \"**/*.tsx\", \"**/*.ts\"]\nalwaysApply: false\n---\n\n# React Router v7 Rules\n\n## Route Modules\n\n- Use route modules as the boundary for route UI, loader data, actions, metadata, and error boundaries.\n- Keep route modules small; move shared UI to components and reusable data access to services.\n- Prefer file-based routing in framework mode when the project is configured for it.\n- Use nested routes for shared layouts and progressive disclosure.\n- Export route-specific `ErrorBoundary` components for recoverable route failures.\n\n## Data Loading\n\n- Use loaders for route data that should be available before render.\n- Keep loaders deterministic and side-effect free.\n- Validate params and search params at the loader boundary.\n- Return typed data and consume it through route hooks rather than duplicating fetch logic in components.\n- Use deferred or streaming patterns only when they improve perceived performance.\n\n## Mutations\n\n- Use actions for route mutations and form submissions.\n- Prefer `Form`, `useFetcher`, and `useSubmit` for progressive enhancement.\n- Revalidate affected loader data after mutations.\n- Handle validation errors as typed action data instead of generic exceptions.\n- Keep server-only secrets and privileged operations out of client actions.\n\n## Navigation and State\n\n- Store shareable state in URL params or search params.\n- Keep ephemeral UI state local to components.\n- Use pending navigation state to show optimistic or loading UI.\n- Avoid global state for data that belongs to route loaders.\n\n## TypeScript and Testing\n\n- Type loader and action return values.\n- Add tests for route loaders, actions, validation failures, and error boundaries.\n- Use integration tests for critical form and navigation flows.\n- Mock network and persistence at the route-service boundary.\n\n## Common Mistakes\n\n- Do not duplicate loader fetches in `useEffect`.\n- Do not mutate data in loaders.\n- Do not hide route errors behind a single generic app-level catch-all.\n- Do not put auth checks only in components when loader data is protected.\n"}