0
# Route Configuration
1
2
Route definition components and utilities for declaring application routes with support for nested routing, dynamic segments, and route data loading.
3
4
## Capabilities
5
6
### Routes
7
8
Container component that renders the first route that matches the current location.
9
10
```typescript { .api }
11
/**
12
* Container for Route components that renders the first matching route
13
* @param props - Routes configuration options
14
* @returns Route matching and rendering component
15
*/
16
function Routes(props: RoutesProps): JSX.Element;
17
18
interface RoutesProps {
19
/** Route components to match against */
20
children?: React.ReactNode;
21
/** Base location for relative matching */
22
location?: Partial<Location> | string;
23
}
24
```
25
26
**Usage Example:**
27
28
```tsx
29
import { Routes, Route } from "react-router-dom";
30
31
function App() {
32
return (
33
<Routes>
34
<Route path="/" element={<Home />} />
35
<Route path="/about" element={<About />} />
36
<Route path="/users/:id" element={<UserProfile />} />
37
</Routes>
38
);
39
}
40
```
41
42
### Route
43
44
Defines a single route with its path, component, and data loading configuration.
45
46
```typescript { .api }
47
/**
48
* Defines a route with path matching and element rendering
49
* @param props - Route configuration including path and element
50
* @returns Route definition for use within Routes
51
*/
52
function Route(props: RouteProps): JSX.Element;
53
54
interface RouteProps {
55
/** URL path pattern to match */
56
path?: string;
57
/** Indicates this is an index route (matches parent's path exactly) */
58
index?: boolean;
59
/** React element to render when route matches */
60
element?: React.ReactNode;
61
/** Error boundary element for this route */
62
errorElement?: React.ReactNode;
63
/** Data loader function */
64
loader?: LoaderFunction;
65
/** Form action handler */
66
action?: ActionFunction;
67
/** Nested route definitions */
68
children?: React.ReactNode;
69
/** Enable case-sensitive path matching */
70
caseSensitive?: boolean;
71
/** Function to determine if route data should revalidate */
72
shouldRevalidate?: ShouldRevalidateFunction;
73
/** Lazy route component loader */
74
lazy?: LazyRouteFunction;
75
}
76
77
type LoaderFunction = (args: LoaderFunctionArgs) =>
78
| Promise<Response>
79
| Response
80
| Promise<any>
81
| any;
82
83
type ActionFunction = (args: ActionFunctionArgs) =>
84
| Promise<Response>
85
| Response
86
| Promise<any>
87
| any;
88
89
interface LoaderFunctionArgs {
90
/** Request object with URL, headers, and body */
91
request: Request;
92
/** Route parameters extracted from URL */
93
params: Params;
94
/** Application context object */
95
context?: any;
96
}
97
98
interface ActionFunctionArgs {
99
/** Request object with form data and method */
100
request: Request;
101
/** Route parameters from URL */
102
params: Params;
103
/** Application context object */
104
context?: any;
105
}
106
107
type ShouldRevalidateFunction = (args: ShouldRevalidateFunctionArgs) => boolean;
108
109
interface ShouldRevalidateFunctionArgs {
110
currentUrl: URL;
111
currentParams: Params;
112
nextUrl: URL;
113
nextParams: Params;
114
formMethod?: string;
115
formAction?: string;
116
formEncType?: string;
117
formData?: FormData;
118
actionResult?: any;
119
}
120
```
121
122
**Usage Examples:**
123
124
```tsx
125
// Basic route
126
<Route path="/users" element={<Users />} />
127
128
// Route with parameters
129
<Route path="/users/:id" element={<UserProfile />} />
130
131
// Index route (matches parent exactly)
132
<Route index element={<Home />} />
133
134
// Route with data loading
135
<Route
136
path="/products/:id"
137
element={<Product />}
138
loader={async ({ params }) => {
139
return fetch(`/api/products/${params.id}`);
140
}}
141
/>
142
143
// Route with form action
144
<Route
145
path="/contact"
146
element={<ContactForm />}
147
action={async ({ request }) => {
148
const formData = await request.formData();
149
return await submitContact(formData);
150
}}
151
/>
152
153
// Nested routes
154
<Route path="/dashboard" element={<Dashboard />}>
155
<Route index element={<DashboardHome />} />
156
<Route path="settings" element={<Settings />} />
157
<Route path="profile" element={<Profile />} />
158
</Route>
159
```
160
161
### Outlet
162
163
Renders child routes in nested routing scenarios.
164
165
```typescript { .api }
166
/**
167
* Renders the matching child route component
168
* @param props - Outlet configuration options
169
* @returns Child route rendering component
170
*/
171
function Outlet(props: OutletProps): JSX.Element;
172
173
interface OutletProps {
174
/** Context data to pass to child routes */
175
context?: unknown;
176
}
177
```
178
179
**Usage Example:**
180
181
```tsx
182
// Parent component
183
function Dashboard() {
184
return (
185
<div>
186
<h1>Dashboard</h1>
187
<nav>
188
<Link to="stats">Statistics</Link>
189
<Link to="settings">Settings</Link>
190
</nav>
191
{/* Child routes render here */}
192
<Outlet />
193
</div>
194
);
195
}
196
197
// Route configuration
198
<Route path="/dashboard" element={<Dashboard />}>
199
<Route path="stats" element={<Statistics />} />
200
<Route path="settings" element={<Settings />} />
201
</Route>
202
```
203
204
### Await
205
206
Component for handling deferred data with Suspense and error boundaries.
207
208
```typescript { .api }
209
/**
210
* Component that resolves deferred data with Suspense support
211
* @param props - Await component configuration
212
* @returns Component that handles async data resolution
213
*/
214
function Await<T>(props: AwaitProps<T>): JSX.Element;
215
216
interface AwaitProps<T> {
217
/** Promise to resolve */
218
resolve: Promise<T>;
219
/** Component to render when promise resolves */
220
children: React.ReactNode | ((value: T) => React.ReactNode);
221
/** Component to render when promise rejects */
222
errorElement?: React.ReactNode | null;
223
}
224
```
225
226
**Usage Examples:**
227
228
```tsx
229
import { Await, useLoaderData, defer } from "react-router-dom";
230
import { Suspense } from "react";
231
232
// Loader that returns deferred data
233
export const userProfileLoader = async ({ params }) => {
234
// Fast data loaded immediately
235
const basicInfo = await fetch(`/api/users/${params.id}/basic`).then(r => r.json());
236
237
// Slow data deferred for streaming
238
const postsPromise = fetch(`/api/users/${params.id}/posts`).then(r => r.json());
239
const analyticsPromise = fetch(`/api/users/${params.id}/analytics`).then(r => r.json());
240
241
return defer({
242
basicInfo,
243
posts: postsPromise,
244
analytics: analyticsPromise
245
});
246
};
247
248
// Component using Await for deferred data
249
function UserProfile() {
250
const { basicInfo, posts, analytics } = useLoaderData<{
251
basicInfo: User;
252
posts: Promise<Post[]>;
253
analytics: Promise<Analytics>;
254
}>();
255
256
return (
257
<div>
258
{/* Immediate data */}
259
<h1>{basicInfo.name}</h1>
260
<p>{basicInfo.email}</p>
261
262
{/* Deferred data with loading states */}
263
<section>
264
<h2>Recent Posts</h2>
265
<Suspense fallback={<div>Loading posts...</div>}>
266
<Await resolve={posts}>
267
<PostsList />
268
</Await>
269
</Suspense>
270
</section>
271
272
<section>
273
<h2>Analytics</h2>
274
<Suspense fallback={<div>Loading analytics...</div>}>
275
<Await
276
resolve={analytics}
277
errorElement={<div>Failed to load analytics</div>}
278
>
279
<AnalyticsDashboard />
280
</Await>
281
</Suspense>
282
</section>
283
</div>
284
);
285
}
286
287
// Component that receives resolved data
288
function PostsList() {
289
const posts = useAsyncValue<Post[]>();
290
291
return (
292
<ul>
293
{posts.map(post => (
294
<li key={post.id}>
295
<h3>{post.title}</h3>
296
<p>{post.excerpt}</p>
297
</li>
298
))}
299
</ul>
300
);
301
}
302
303
// Component with error handling
304
function AnalyticsDashboard() {
305
const analytics = useAsyncValue<Analytics>();
306
307
return (
308
<div>
309
<p>Views: {analytics.views}</p>
310
<p>Engagement: {analytics.engagement}%</p>
311
</div>
312
);
313
}
314
315
// Error boundary for async errors
316
function AsyncErrorBoundary() {
317
const error = useAsyncError();
318
319
return (
320
<div className="error">
321
<h3>Something went wrong</h3>
322
<p>{error instanceof Error ? error.message : "Unknown error"}</p>
323
</div>
324
);
325
}
326
```
327
328
### Route Objects
329
330
Declarative route configuration objects for use with router creation functions.
331
332
```typescript { .api }
333
interface RouteObject {
334
/** URL path pattern to match */
335
path?: string;
336
/** Indicates this is an index route */
337
index?: boolean;
338
/** Nested route definitions */
339
children?: RouteObject[];
340
/** Enable case-sensitive matching */
341
caseSensitive?: boolean;
342
/** Unique route identifier */
343
id?: string;
344
/** Data loader function */
345
loader?: LoaderFunction;
346
/** Form action handler */
347
action?: ActionFunction;
348
/** Component to render */
349
element?: React.ReactNode | null;
350
/** Error boundary component */
351
errorElement?: React.ReactNode | null;
352
/** Revalidation control function */
353
shouldRevalidate?: ShouldRevalidateFunction;
354
/** Lazy component loader */
355
lazy?: LazyRouteFunction;
356
}
357
358
interface IndexRouteObject extends Omit<RouteObject, "path" | "children"> {
359
index: true;
360
}
361
362
interface NonIndexRouteObject extends RouteObject {
363
path: string;
364
index?: false;
365
}
366
367
interface DataRouteObject extends RouteObject {
368
/** Nested routes with data loading */
369
children?: DataRouteObject[];
370
/** Required unique identifier */
371
id: string;
372
}
373
374
type LazyRouteFunction<T extends RouteObject = RouteObject> = () => Promise<LazyRouteModule<T>>;
375
376
interface LazyRouteModule<T extends RouteObject = RouteObject> {
377
Component?: React.ComponentType<any> | null;
378
element?: React.ReactNode | null;
379
errorElement?: React.ReactNode | null;
380
loader?: T["loader"];
381
action?: T["action"];
382
shouldRevalidate?: T["shouldRevalidate"];
383
}
384
```
385
386
**Usage Example:**
387
388
```tsx
389
import { createBrowserRouter } from "react-router-dom";
390
391
const routes: RouteObject[] = [
392
{
393
path: "/",
394
element: <Root />,
395
errorElement: <ErrorBoundary />,
396
loader: rootLoader,
397
children: [
398
{
399
index: true,
400
element: <Home />,
401
},
402
{
403
path: "products/:id",
404
element: <Product />,
405
loader: productLoader,
406
action: productAction,
407
},
408
],
409
},
410
];
411
412
const router = createBrowserRouter(routes);
413
```
414
415
### Route Utilities
416
417
Functions for working with routes programmatically.
418
419
```typescript { .api }
420
/**
421
* Create route objects from JSX Route elements
422
* @param children - JSX Route elements
423
* @returns Array of RouteObject definitions
424
*/
425
function createRoutesFromElements(children: React.ReactNode): RouteObject[];
426
427
/** Alias for createRoutesFromElements */
428
function createRoutesFromChildren(children: React.ReactNode): RouteObject[];
429
430
/**
431
* Render matched routes as React elements
432
* @param matches - Route matches to render
433
* @param parentMatches - Parent route matches for context
434
* @returns Rendered route elements
435
*/
436
function renderMatches(
437
matches: RouteMatch[] | null,
438
parentMatches?: RouteMatch[]
439
): React.ReactElement | null;
440
441
interface RouteMatch<ParamKey extends string = string> {
442
/** Matched route parameters */
443
params: Params<ParamKey>;
444
/** Matched pathname */
445
pathname: string;
446
/** Pattern info used for matching */
447
pathnameBase: string;
448
/** Route definition */
449
route: RouteObject;
450
}
451
```
452
453
## Route Patterns
454
455
### Dynamic Segments
456
457
```tsx
458
// URL parameter
459
<Route path="/users/:userId" element={<User />} />
460
461
// Optional parameter
462
<Route path="/posts/:postId?" element={<Post />} />
463
464
// Multiple parameters
465
<Route path="/users/:userId/posts/:postId" element={<UserPost />} />
466
```
467
468
### Wildcard Routes
469
470
```tsx
471
// Catch-all route
472
<Route path="*" element={<NotFound />} />
473
474
// Splat routes (capture remaining path)
475
<Route path="/files/*" element={<FileBrowser />} />
476
```
477
478
### Index Routes
479
480
```tsx
481
// Renders at parent's exact path
482
<Route path="/dashboard" element={<Dashboard />}>
483
<Route index element={<DashboardHome />} />
484
<Route path="settings" element={<Settings />} />
485
</Route>
486
```