0
# React Router Integration
1
2
Complete re-export of React Router components, hooks, and utilities for routing functionality, seamlessly integrated with Remix's data loading and server-side rendering capabilities.
3
4
## Capabilities
5
6
### Navigation Components
7
8
Core React Router components for declarative navigation and route rendering.
9
10
```typescript { .api }
11
/**
12
* Declarative navigation component that triggers navigation when rendered
13
* @param props - Navigation configuration
14
* @returns React element that triggers navigation
15
*/
16
function Navigate(props: NavigateProps): ReactElement;
17
18
/**
19
* Renders the child route component for the current location
20
* @param props - Optional outlet configuration
21
* @returns React element containing the matched child route
22
*/
23
function Outlet(props?: OutletProps): ReactElement;
24
25
/**
26
* Container component for route definitions
27
* @param props - Routes configuration
28
* @returns React element containing route matching logic
29
*/
30
function Routes(props: RoutesProps): ReactElement;
31
32
/**
33
* Defines a single route in the application
34
* @param props - Route configuration
35
* @returns Route definition (not directly rendered)
36
*/
37
function Route(props: RouteProps): ReactElement;
38
39
interface NavigateProps {
40
/** Path to navigate to */
41
to: string | Partial<Path>;
42
/** Whether to replace the current history entry */
43
replace?: boolean;
44
/** State to pass with the navigation */
45
state?: any;
46
/** Relative path resolution */
47
relative?: "route" | "path";
48
}
49
50
interface OutletProps {
51
/** Context data to pass to child routes */
52
context?: unknown;
53
}
54
55
interface RouteProps {
56
/** Path pattern to match */
57
path?: string;
58
/** Route element to render */
59
element?: ReactElement;
60
/** Index route indicator */
61
index?: boolean;
62
/** Child routes */
63
children?: ReactNode;
64
/** Whether path matching is case sensitive */
65
caseSensitive?: boolean;
66
/** Route ID for data loading */
67
id?: string;
68
/** Loader function for data loading */
69
loader?: LoaderFunction;
70
/** Action function for form handling */
71
action?: ActionFunction;
72
/** Error boundary element */
73
errorElement?: ReactElement;
74
/** Route handle for custom metadata */
75
handle?: RouteHandle;
76
/** Should revalidate function */
77
shouldRevalidate?: ShouldRevalidateFunction;
78
}
79
```
80
81
**Usage Examples:**
82
83
```typescript
84
import { Routes, Route, Navigate, Outlet } from "@remix-run/react";
85
86
// Basic route definitions
87
function AppRoutes() {
88
return (
89
<Routes>
90
<Route path="/" element={<Home />} />
91
<Route path="/about" element={<About />} />
92
<Route path="/users" element={<UsersLayout />}>
93
<Route index element={<UsersList />} />
94
<Route path=":userId" element={<UserDetail />} />
95
</Route>
96
<Route path="/old-path" element={<Navigate to="/new-path" replace />} />
97
</Routes>
98
);
99
}
100
101
// Layout with outlet
102
function UsersLayout() {
103
return (
104
<div>
105
<h1>Users</h1>
106
<nav>{/* user navigation */}</nav>
107
<main>
108
<Outlet />
109
</main>
110
</div>
111
);
112
}
113
```
114
115
### Navigation Hooks
116
117
Hooks for programmatic navigation and location access.
118
119
```typescript { .api }
120
/**
121
* Returns a function for programmatic navigation
122
* @returns Function to navigate to different routes
123
*/
124
function useNavigate(): NavigateFunction;
125
126
/**
127
* Returns the current location object
128
* @returns Current location with pathname, search, hash, state, and key
129
*/
130
function useLocation(): Location;
131
132
/**
133
* Returns the current navigation state
134
* @returns Information about ongoing navigation
135
*/
136
function useNavigation(): Navigation;
137
138
/**
139
* Returns the type of the current navigation
140
* @returns Navigation type (PUSH, REPLACE, or POP)
141
*/
142
function useNavigationType(): NavigationType;
143
144
type NavigateFunction = (
145
to: string | number | Partial<Path>,
146
options?: NavigateOptions
147
) => void;
148
149
interface NavigateOptions {
150
replace?: boolean;
151
state?: any;
152
preventScrollReset?: boolean;
153
relative?: "route" | "path";
154
}
155
156
interface Location {
157
/** Current pathname */
158
pathname: string;
159
/** Current search string */
160
search: string;
161
/** Current hash fragment */
162
hash: string;
163
/** Navigation state */
164
state: unknown;
165
/** Unique key for this location */
166
key: string;
167
}
168
169
interface Navigation {
170
/** Current navigation state */
171
state: "idle" | "loading" | "submitting";
172
/** Target location for navigation */
173
location?: Location;
174
/** Form data being submitted */
175
formData?: FormData;
176
/** JSON data being submitted */
177
json?: any;
178
/** Text data being submitted */
179
text?: string;
180
/** Form method */
181
formMethod?: string;
182
/** Form action */
183
formAction?: string;
184
}
185
186
type NavigationType = "POP" | "PUSH" | "REPLACE";
187
```
188
189
**Usage Examples:**
190
191
```typescript
192
import { useNavigate, useLocation, useNavigation } from "@remix-run/react";
193
194
// Programmatic navigation
195
function LoginButton() {
196
const navigate = useNavigate();
197
const location = useLocation();
198
199
const handleLogin = async () => {
200
const success = await login();
201
if (success) {
202
// Navigate to the page they were trying to access, or home
203
const from = location.state?.from?.pathname || "/";
204
navigate(from, { replace: true });
205
}
206
};
207
208
return <button onClick={handleLogin}>Login</button>;
209
}
210
211
// Location-based rendering
212
function LocationDisplay() {
213
const location = useLocation();
214
215
return (
216
<div>
217
<p>Current path: {location.pathname}</p>
218
<p>Search params: {location.search}</p>
219
{location.state && <p>State: {JSON.stringify(location.state)}</p>}
220
</div>
221
);
222
}
223
224
// Navigation state indicator
225
function NavigationIndicator() {
226
const navigation = useNavigation();
227
228
if (navigation.state === "loading") {
229
return <div className="loading-bar">Loading...</div>;
230
}
231
232
if (navigation.state === "submitting") {
233
return <div className="loading-bar">Submitting...</div>;
234
}
235
236
return null;
237
}
238
```
239
240
### Route Parameters and Search
241
242
Hooks for accessing route parameters and URL search parameters.
243
244
```typescript { .api }
245
/**
246
* Returns the current route parameters
247
* @returns Object containing route parameters
248
*/
249
function useParams<K extends string = string>(): Readonly<Params<K>>;
250
251
/**
252
* Returns the current URL search parameters
253
* @returns Tuple of URLSearchParams and setter function
254
*/
255
function useSearchParams(): [URLSearchParams, SetURLSearchParams];
256
257
/**
258
* Returns a resolved path object
259
* @param to - Path to resolve
260
* @param options - Resolution options
261
* @returns Resolved path object
262
*/
263
function useResolvedPath(to: string | Partial<Path>, options?: { relative?: "route" | "path" }): Path;
264
265
type Params<K extends string = string> = {
266
readonly [key in K]: string | undefined;
267
};
268
269
type SetURLSearchParams = (
270
nextInit: URLSearchParamsInit | ((prev: URLSearchParams) => URLSearchParamsInit),
271
navigateOptions?: NavigateOptions
272
) => void;
273
```
274
275
**Usage Examples:**
276
277
```typescript
278
import { useParams, useSearchParams } from "@remix-run/react";
279
280
// Route parameters
281
function UserProfile() {
282
const { userId } = useParams();
283
284
if (!userId) {
285
return <div>User not found</div>;
286
}
287
288
return <div>User ID: {userId}</div>;
289
}
290
291
// Search parameters
292
function ProductFilter() {
293
const [searchParams, setSearchParams] = useSearchParams();
294
295
const category = searchParams.get("category") || "all";
296
const sortBy = searchParams.get("sort") || "name";
297
298
const updateFilter = (key: string, value: string) => {
299
setSearchParams(prev => {
300
const newParams = new URLSearchParams(prev);
301
newParams.set(key, value);
302
return newParams;
303
});
304
};
305
306
return (
307
<div>
308
<select
309
value={category}
310
onChange={(e) => updateFilter("category", e.target.value)}
311
>
312
<option value="all">All Categories</option>
313
<option value="electronics">Electronics</option>
314
<option value="clothing">Clothing</option>
315
</select>
316
317
<select
318
value={sortBy}
319
onChange={(e) => updateFilter("sort", e.target.value)}
320
>
321
<option value="name">Name</option>
322
<option value="price">Price</option>
323
<option value="date">Date</option>
324
</select>
325
</div>
326
);
327
}
328
```
329
330
### Additional Routing Utilities
331
332
Additional hooks and utilities for advanced routing scenarios.
333
334
```typescript { .api }
335
/**
336
* Returns the current route match
337
* @param pattern - Pattern to match against
338
* @returns Match object or null
339
*/
340
function useMatch<T extends string>(pattern: PathPattern<T> | string): PathMatch<T> | null;
341
342
/**
343
* Returns an href string for the given path
344
* @param to - Path to generate href for
345
* @param options - Resolution options
346
* @returns href string
347
*/
348
function useHref(to: string | Partial<Path>, options?: { relative?: "route" | "path" }): string;
349
350
/**
351
* Returns whether the component is rendered within a router context
352
* @returns Boolean indicating if in router context
353
*/
354
function useInRouterContext(): boolean;
355
356
/**
357
* Returns outlet context data
358
* @returns Context data passed from parent route
359
*/
360
function useOutletContext<T = unknown>(): T;
361
362
/**
363
* Returns the current outlet element
364
* @returns The current outlet element
365
*/
366
function useOutlet(): ReactElement | null;
367
368
/**
369
* Returns revalidator for manually triggering data revalidation
370
* @returns Revalidator with revalidate function and state
371
*/
372
function useRevalidator(): Revalidator;
373
374
interface Revalidator {
375
/** Function to trigger revalidation */
376
revalidate(): void;
377
/** Current revalidation state */
378
state: "idle" | "loading";
379
}
380
381
/**
382
* Registers a callback to be called before the page unloads
383
* @param callback - Function to call before unload
384
*/
385
function useBeforeUnload(callback: (event: BeforeUnloadEvent) => void): void;
386
387
/**
388
* Returns the action URL for the current form context
389
* @returns The action URL string
390
*/
391
function useFormAction(): string;
392
393
/**
394
* Returns a click handler for programmatic navigation
395
* @param to - Navigation target
396
* @param options - Navigation options
397
* @returns Click handler function
398
*/
399
function useLinkClickHandler<E extends Element = HTMLAnchorElement>(
400
to: To,
401
options?: {
402
target?: React.HTMLAttributeAnchorTarget;
403
replace?: boolean;
404
state?: any;
405
preventScrollReset?: boolean;
406
relative?: RelativeRoutingType;
407
}
408
): (event: React.MouseEvent<E, MouseEvent>) => void;
409
410
/**
411
* Returns a submit function for programmatic form submission
412
* @returns Submit function
413
*/
414
function useSubmit(): SubmitFunction;
415
416
/**
417
* Returns a blocker for preventing navigation
418
* @param blocker - Blocker function
419
* @returns Blocker state
420
*/
421
function useBlocker(blocker: BlockerFunction): Blocker;
422
423
/**
424
* Returns whether a view transition is active for the given navigation
425
* @param to - Navigation target
426
* @param opts - Options for relative navigation
427
* @returns Whether view transition is active
428
*/
429
function useViewTransitionState(to: To, opts?: { relative?: RelativeRoutingType }): boolean;
430
431
/**
432
* Prompts the user before navigation (unstable API)
433
* @param message - Prompt message or boolean to enable/disable
434
*/
435
function unstable_usePrompt(message: string | boolean): void;
436
437
/**
438
* Returns the current async error, if any
439
* @returns Current async error or undefined
440
*/
441
function useAsyncError(): Error | undefined;
442
443
/**
444
* Returns the resolved async value
445
* @returns The resolved async value
446
*/
447
function useAsyncValue<T = unknown>(): T;
448
449
/**
450
* Returns all active fetchers
451
* @returns Array of active fetchers
452
*/
453
function useFetchers(): Fetcher[];
454
455
/**
456
* Returns the current route error
457
* @returns Current route error
458
*/
459
function useRouteError(): unknown;
460
461
/**
462
* Renders routes from route objects
463
* @param routes - Route objects to render
464
* @param locationArg - Optional location override
465
* @returns Rendered routes
466
*/
467
function useRoutes(routes: RouteObject[], locationArg?: Partial<Location> | string): React.ReactElement | null;
468
```
469
470
### Routing Utilities
471
472
Utility functions for route manipulation and path handling.
473
474
```typescript { .api }
475
/**
476
* Creates a path string from a location object
477
* @param location - Location object
478
* @returns Path string
479
*/
480
function createPath(location: Partial<Location | Path>): string;
481
482
/**
483
* Creates routes from React children elements
484
* @param children - Route elements
485
* @returns Route objects
486
*/
487
function createRoutesFromChildren(children: ReactNode): RouteObject[];
488
489
/**
490
* Creates routes from React elements
491
* @param elements - Route elements
492
* @returns Route objects
493
*/
494
function createRoutesFromElements(elements: ReactNode): RouteObject[];
495
496
/**
497
* Creates URLSearchParams from init value
498
* @param init - Initial search params
499
* @returns URLSearchParams instance
500
*/
501
function createSearchParams(init?: URLSearchParamsInit): URLSearchParams;
502
503
/**
504
* Generates a path with parameters filled in
505
* @param pattern - Path pattern
506
* @param params - Parameters to fill
507
* @returns Generated path
508
*/
509
function generatePath<Path extends string>(pattern: Path, params?: PathParams<Path>): string;
510
511
/**
512
* Matches a path against a pattern
513
* @param pattern - Pattern to match
514
* @param pathname - Path to test
515
* @returns Match result or null
516
*/
517
function matchPath<ParamKey extends string = string>(
518
pattern: PathPattern<ParamKey> | string,
519
pathname: string
520
): PathMatch<ParamKey> | null;
521
522
/**
523
* Parses a path string into a path object
524
* @param path - Path string
525
* @returns Path object
526
*/
527
function parsePath(path: string): Partial<Path>;
528
529
/**
530
* Resolves a path relative to the current location
531
* @param to - Path to resolve
532
* @param fromPathname - Base pathname
533
* @returns Resolved path
534
*/
535
function resolvePath(to: string | Partial<Path>, fromPathname?: string): Path;
536
```
537
538
## Implementation Notes
539
540
- **Full Compatibility**: All React Router functionality is preserved and enhanced with Remix features
541
- **Server-Side Rendering**: All components and hooks work correctly during SSR
542
- **Type Safety**: Full TypeScript support with proper type inference
543
- **Data Integration**: Navigation hooks integrate with Remix's data loading system
544
- **Error Handling**: Route-level error boundaries work seamlessly with Remix error handling
545
- **Performance**: Client-side navigation is optimized with prefetching and caching