| name | react-router-v7-app |
| description | Implements React Router v7 app structure, routing patterns, and component templates. Use when creating or modifying React Router v7 applications to ensure consistent folder structure, data loading patterns, and component architecture. |
React Router v7 App Implementation
1. Route Structure
- Use file-based routing in
app/routes/.
- Route files:
route.tsx for route components.
- Prefer folder routes like
users.$id/route.tsx when a route needs colocated helpers, components, or tests; sibling files in the folder do not become routes.
- If tests live under
app/routes/, configure flatRoutes({ ignoredRouteFiles: [...] }) to exclude *.test.* and *.spec.* from route discovery.
- Use underscore prefix for route groups:
_app, _landing.
- Use dot notation for nested routes:
users.$id.tsx.
2. Data Loading Patterns
- Use
loader functions for server-side data fetching.
- Use
action functions for form submissions and mutations.
- Leverage
useLoaderData() and useActionData() hooks.
- Handle loading states with
useNavigation().
3. Route Component Structure
Use arrow functions for all exports.
import type { Route } from './+types/route';
export const loader = async ({ request, params, context }: Route.LoaderArgs) => {
return { ... };
};
export const action = async ({ request, params, context }: Route.ActionArgs) => {
return { ... };
};
const Page = ({ loaderData, actionData }: Route.ComponentProps) => {
return (
<div>
{/* Content */}
</div>
);
};
export default Page;
4. Error Handling
- Use
ErrorBoundary components for route-level error handling.
- Implement proper error responses in loaders/actions.
- Use
isRouteErrorResponse() for typed error handling.
5. Meta and Headers
- Export
meta function for dynamic page metadata.
- Export
headers function for custom HTTP headers.
- Use proper SEO practices with meta tags.
6. Project Structure
The app folder should follow this structure:
public
|
app
|
+-- components
|
+-- config
|
+-- constants
|
+-- hooks
|
+-- lib
|
+-- routes
|
+-- stores
|
+-- testing
|
+-- types
|
+-- utils
|
app/components
- Place app-wide shared components under
app/components.
- Components in this directory should be reusable across multiple routes or features.
- Do not place feature-scoped components here; keep them inside each route directory's
components folder.
- Use lowercase kebab-case for all component file names in both
app/components and route-scoped components directories.
- Examples:
app-header.tsx, empty-state.tsx, todo-form.tsx.
app/components
|
+-- ui
| |
| +-- button.tsx
| ...
|
+-- app-header.tsx
+-- empty-state.tsx
|
routes
Use collocation to group files related to layouts and pages.
- Keep the route module in
route.tsx and colocate route-local tests as route.test.ts only when route discovery is configured to ignore test/spec files.
app/routes/_app._index
|
+-- assets
|
+-- components
|
+-- constants
|
+-- hooks
|
+-- services
|
+-- stores
|
+-- types
|
+-- utils
Example structure:
app/routes
|
+-- _app
| |
| +-- route.tsx
|
+-- _app.index
| |
| +-- route.tsx
|
+-- _app.todos
| |
| +-- components
| |
| +-- types
| |
| +-- route.tsx
|
+-- _app.todos._index
| |
| +-- components
| |
| +-- route.tsx
|
+-- _app.todos.$todoId.edit._index
| |
| +-- components
| |
| +-- hooks
| |
| +-- stores
| |
| +-- route.tsx
|
+-- _app.todos.$todoId_.delete
|
+-- route.tsx
7. Advanced Routing Patterns
Nested Routes for UI Segmentation
Use nested routes to split complex pages (e.g., tabs) into independent route modules.
- Parent route renders shared UI and
<Outlet />.
- Child routes handle their own data loading (
loader) and mutations (action).
- Reduces prop drilling and isolates logic.
Example (Tabs):
routes/user.tsx: Renders tabs navigation and <Outlet />.
routes/user.profile.tsx: Renders profile tab content.
routes/user.account.tsx: Renders account tab content.
Route-based Modals
Manage modal state via URLs instead of useState.
- Define the modal as a child route.
- Parent route renders the background UI and
<Outlet />.
- Modal component renders inside the
<Outlet /> (often using a Dialog component).
- Closing the modal is a navigation action (e.g.,
<Link to="..">).
Example:
routes/users.tsx: Lists users and contains <Outlet />.
routes/users.new.tsx: Renders the "Create User" modal.