0
# Navigation & Links
1
2
Navigation utilities, link components, and programmatic navigation with type-safe parameter handling, URL masking, and advanced navigation features.
3
4
## Capabilities
5
6
### Redirection
7
8
Create redirect responses for use in route loaders and actions.
9
10
```typescript { .api }
11
/**
12
* Create a redirect response
13
* @param options - Redirect configuration options
14
* @returns Redirect object for throwing from loaders/actions
15
*/
16
function redirect<TRouter extends AnyRouter = AnyRouter>(
17
options: RedirectOptions<TRouter>
18
): Redirect;
19
20
interface RedirectOptions<TRouter extends AnyRouter = AnyRouter> {
21
/** Redirect destination path */
22
to?: string;
23
/** Search parameters for redirect */
24
search?: Record<string, any> | ((current: any) => Record<string, any>);
25
/** Path parameters for redirect */
26
params?: Record<string, any>;
27
/** Hash fragment for redirect */
28
hash?: string | ((current: string) => string);
29
/** History state */
30
state?: any;
31
/** Use replace instead of push */
32
replace?: boolean;
33
/** HTTP status code (SSR) */
34
statusCode?: number;
35
/** HTTP headers (SSR) */
36
headers?: Record<string, string>;
37
}
38
39
/**
40
* Type guard for redirect objects
41
* @param obj - Object to check
42
* @returns Whether object is a redirect
43
*/
44
function isRedirect(obj: any): obj is Redirect;
45
46
interface Redirect {
47
code: "REDIRECT";
48
statusCode: number;
49
headers: Record<string, string>;
50
href: string;
51
}
52
```
53
54
**Usage Examples:**
55
56
```typescript
57
import { redirect } from "@tanstack/react-router";
58
59
// In route loader
60
const postRoute = createRoute({
61
path: "/posts/$postId",
62
loader: async ({ params, context }) => {
63
const post = await fetchPost(params.postId);
64
65
// Redirect if post not found
66
if (!post) {
67
throw redirect({
68
to: "/404",
69
statusCode: 404,
70
});
71
}
72
73
// Redirect if user doesn't have permission
74
if (!context.user.canViewPost(post)) {
75
throw redirect({
76
to: "/login",
77
search: { redirect: `/posts/${params.postId}` },
78
replace: true,
79
});
80
}
81
82
return { post };
83
},
84
});
85
86
// Conditional redirect in component
87
function ProtectedRoute() {
88
const { user } = useRouteContext();
89
90
if (!user) {
91
throw redirect({ to: "/login" });
92
}
93
94
return <Dashboard />;
95
}
96
```
97
98
### Link Utilities
99
100
Utilities for creating custom link components and validating link options.
101
102
```typescript { .api }
103
/**
104
* Create a custom link component with any element
105
* @param Comp - Base component to wrap with link functionality
106
* @returns Link component with router functionality
107
*/
108
function createLink<TComp extends React.ComponentType<any>>(
109
Comp: TComp
110
): LinkComponent<TComp>;
111
112
/**
113
* Validate and return link options with type safety
114
* @param options - Link options to validate
115
* @returns Validated link options
116
*/
117
function linkOptions<
118
TRouter extends AnyRouter = RegisteredRouter,
119
TFrom extends string = string,
120
TTo extends string | undefined = undefined,
121
TMaskFrom extends string = TFrom,
122
TMaskTo extends string = ""
123
>(
124
options: LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>
125
): LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>;
126
127
type LinkComponent<TComp> = React.ForwardRefExoticComponent<
128
Omit<React.ComponentProps<TComp>, keyof LinkProps> & LinkProps
129
>;
130
```
131
132
**Usage Examples:**
133
134
```typescript
135
import { createLink, linkOptions } from "@tanstack/react-router";
136
137
// Create custom link with button
138
const ButtonLink = createLink("button");
139
140
function CustomNavigation() {
141
return (
142
<ButtonLink
143
to="/dashboard"
144
params={{ userId: "123" }}
145
activeProps={{ className: "active-button" }}
146
>
147
Dashboard
148
</ButtonLink>
149
);
150
}
151
152
// Create link with custom component
153
const CardLink = createLink(({ children, ...props }) => (
154
<div className="card" {...props}>
155
{children}
156
</div>
157
));
158
159
// Validate link options
160
function ValidatedLink({ to, ...options }) {
161
const validatedOptions = linkOptions({
162
to,
163
preload: "intent",
164
activeOptions: { exact: true },
165
...options,
166
});
167
168
return <Link {...validatedOptions} />;
169
}
170
```
171
172
### Navigation History
173
174
Create and manage browser history for navigation.
175
176
```typescript { .api }
177
/**
178
* Create a browser history instance
179
* @param options - Browser history options
180
* @returns Browser history instance
181
*/
182
function createBrowserHistory(options?: {
183
basename?: string;
184
window?: Window;
185
}): RouterHistory;
186
187
/**
188
* Create a hash history instance
189
* @param options - Hash history options
190
* @returns Hash history instance
191
*/
192
function createHashHistory(options?: {
193
basename?: string;
194
window?: Window;
195
}): RouterHistory;
196
197
/**
198
* Create a memory history instance for testing/SSR
199
* @param options - Memory history options
200
* @returns Memory history instance
201
*/
202
function createMemoryHistory(options?: {
203
initialEntries?: string[];
204
initialIndex?: number;
205
}): RouterHistory;
206
207
/**
208
* Create a history instance (base function)
209
* @param options - History options
210
* @returns History instance
211
*/
212
function createHistory(options: {
213
getLocation: () => HistoryLocation;
214
listener: (fn: () => void) => () => void;
215
pushState: (path: string, state?: any) => void;
216
replaceState: (path: string, state?: any) => void;
217
go: (n: number) => void;
218
back: () => void;
219
forward: () => void;
220
createHref?: (path: string) => string;
221
}): RouterHistory;
222
```
223
224
**Usage Examples:**
225
226
```typescript
227
import { createBrowserHistory, createMemoryHistory, createRouter } from "@tanstack/react-router";
228
229
// Browser history with basename
230
const history = createBrowserHistory({
231
basename: "/app",
232
});
233
234
const router = createRouter({
235
routeTree,
236
history,
237
});
238
239
// Memory history for testing
240
const testHistory = createMemoryHistory({
241
initialEntries: ["/", "/about", "/contact"],
242
initialIndex: 1, // Start at /about
243
});
244
245
// Hash history
246
const hashHistory = createHashHistory();
247
```
248
249
### Navigation Blocking
250
251
Utilities for blocking navigation under certain conditions.
252
253
```typescript { .api }
254
type BlockerFn = (args: {
255
fromLocation: ParsedLocation;
256
toLocation: ParsedLocation;
257
}) => boolean | Promise<boolean>;
258
259
type ShouldBlockFn = (
260
fromLocation: ParsedLocation,
261
toLocation: ParsedLocation
262
) => boolean;
263
```
264
265
### Route Matching Utilities
266
267
Utilities for checking route matches and building navigation options.
268
269
```typescript { .api }
270
/**
271
* Check if current location matches route pattern
272
* @param basepath - Base path
273
* @param currentPathname - Current pathname
274
* @param matchLocation - Location to match against
275
* @returns Match result or false
276
*/
277
function matchPathname(
278
basepath: string,
279
currentPathname: string,
280
matchLocation: MatchLocation
281
): MatchPathResult | false;
282
283
/**
284
* Match route by path pattern
285
* @param basepath - Base path
286
* @param currentPathname - Current pathname
287
* @param matchLocation - Location to match against
288
* @returns Match result or false
289
*/
290
function matchByPath(
291
basepath: string,
292
currentPathname: string,
293
matchLocation: MatchLocation
294
): MatchPathResult | false;
295
296
interface MatchLocation {
297
to: string;
298
params?: Record<string, any>;
299
search?: Record<string, any>;
300
hash?: string;
301
fuzzy?: boolean;
302
includeSearch?: boolean;
303
includeHash?: boolean;
304
}
305
306
interface MatchPathResult {
307
params: Record<string, string>;
308
}
309
```
310
311
### Build Navigation Functions
312
313
Utilities for building navigation and location objects.
314
315
```typescript { .api }
316
type BuildLocationFn<TRouter extends AnyRouter = AnyRouter> = <
317
TFrom extends RoutePaths<TRouter> = "/",
318
TTo extends string = "."
319
>(
320
opts: BuildLocationOptions<TRouter, TFrom, TTo>
321
) => ParsedLocation;
322
323
interface BuildLocationOptions<TRouter extends AnyRouter, TFrom extends RoutePaths<TRouter>, TTo extends string> {
324
to?: TTo;
325
from?: TFrom;
326
params?: Record<string, any>;
327
search?: Record<string, any> | ((prev: any) => Record<string, any>);
328
hash?: string | ((prev: string) => string);
329
state?: any;
330
}
331
332
type NavigateFn<TRouter extends AnyRouter = AnyRouter> = <
333
TFrom extends RoutePaths<TRouter> = "/",
334
TTo extends string = "."
335
>(
336
opts: NavigateOptions<TRouter, TFrom, TTo>
337
) => Promise<void>;
338
```
339
340
### Navigation Options Validation
341
342
Type-safe validation utilities for navigation options.
343
344
```typescript { .api }
345
type ValidateNavigateOptions<TRouter extends AnyRouter, TFrom extends string, TTo extends string> =
346
NavigateOptions<TRouter, TFrom, TTo>;
347
348
type ValidateNavigateOptionsArray<T> = T extends ReadonlyArray<infer U>
349
? U extends { to: infer TTo; from?: infer TFrom }
350
? TTo extends string
351
? TFrom extends string | undefined
352
? ValidateNavigateOptions<RegisteredRouter, TFrom extends string ? TFrom : "/", TTo>
353
: never
354
: never
355
: never
356
: never;
357
358
type ValidateRedirectOptions<TRouter extends AnyRouter, TFrom extends string, TTo extends string> =
359
RedirectOptions<TRouter>;
360
361
type ValidateRedirectOptionsArray<T> = T extends ReadonlyArray<infer U>
362
? U extends { to: infer TTo; from?: infer TFrom }
363
? TTo extends string
364
? TFrom extends string | undefined
365
? ValidateRedirectOptions<RegisteredRouter, TFrom extends string ? TFrom : "/", TTo>
366
: never
367
: never
368
: never
369
: never;
370
```
371
372
## Types
373
374
### Core Navigation Types
375
376
```typescript { .api }
377
interface NavigateOptions<
378
TRouter extends AnyRouter = AnyRouter,
379
TFrom extends RoutePaths<TRouter> = "/",
380
TTo extends string = "."
381
> {
382
/** Destination path */
383
to?: TTo;
384
/** Source path for relative navigation */
385
from?: TFrom;
386
/** Path parameters */
387
params?: MakeRouteMatch<TRouter, TFrom, TTo>["params"];
388
/** Search parameters */
389
search?: MakeRouteMatch<TRouter, TFrom, TTo>["search"] | ((prev: any) => any);
390
/** Hash fragment */
391
hash?: string | ((prev: string) => string);
392
/** History state */
393
state?: any;
394
/** Route mask options */
395
mask?: ToMaskOptions<TRouter, TFrom, TTo>;
396
/** Use replace instead of push */
397
replace?: boolean;
398
/** Reset scroll position */
399
resetScroll?: boolean;
400
/** Scroll hash target into view */
401
hashScrollIntoView?: boolean;
402
/** Wrap navigation in startTransition */
403
startTransition?: boolean;
404
/** Enable view transitions */
405
viewTransition?: boolean;
406
/** Ignore navigation blockers */
407
ignoreBlocker?: boolean;
408
}
409
410
interface LinkOptions<
411
TRouter extends AnyRouter = AnyRouter,
412
TFrom extends string = string,
413
TTo extends string | undefined = undefined,
414
TMaskFrom extends string = TFrom,
415
TMaskTo extends string = ""
416
> extends NavigateOptions<TRouter, TFrom, TTo> {
417
/** Props when link is active */
418
activeProps?:
419
| React.AnchorHTMLAttributes<HTMLAnchorElement>
420
| (() => React.AnchorHTMLAttributes<HTMLAnchorElement>);
421
/** Props when link is inactive */
422
inactiveProps?:
423
| React.AnchorHTMLAttributes<HTMLAnchorElement>
424
| (() => React.AnchorHTMLAttributes<HTMLAnchorElement>);
425
/** Active link matching options */
426
activeOptions?: ActiveLinkOptions;
427
/** Preload strategy */
428
preload?: false | "intent" | "render" | "viewport";
429
/** Preload delay in milliseconds */
430
preloadDelay?: number;
431
/** Disabled state */
432
disabled?: boolean;
433
}
434
435
interface ActiveLinkOptions {
436
/** Exact path matching */
437
exact?: boolean;
438
/** Include search parameters in matching */
439
includeSearch?: boolean;
440
/** Include hash in matching */
441
includeHash?: boolean;
442
}
443
```
444
445
### Route Masking Types
446
447
```typescript { .api }
448
interface ToMaskOptions<
449
TRouter extends AnyRouter = AnyRouter,
450
TFrom extends string = string,
451
TTo extends string = string
452
> {
453
/** Masked destination */
454
to?: string;
455
/** Masked parameters */
456
params?: Record<string, any>;
457
/** Masked search parameters */
458
search?: Record<string, any> | ((prev: any) => any);
459
/** Masked hash */
460
hash?: string | ((prev: string) => string);
461
/** Unmask on reload */
462
unmaskOnReload?: boolean;
463
}
464
465
interface RouteMask {
466
from: string;
467
to: string;
468
params?: Record<string, any>;
469
search?: Record<string, any>;
470
hash?: string;
471
unmaskOnReload?: boolean;
472
}
473
```
474
475
### Path Resolution Types
476
477
```typescript { .api }
478
type ToPathOption<
479
TRouter extends AnyRouter = AnyRouter,
480
TFrom extends RoutePaths<TRouter> = "/",
481
TTo extends string = string
482
> = TTo | RelativeToPathAutoComplete<TRouter, TFrom, TTo>;
483
484
type RelativeToPathAutoComplete<
485
TRouter extends AnyRouter,
486
TFrom extends string,
487
TTo extends string
488
> = TTo extends `..${infer _}`
489
? "../"
490
: TTo extends `./${infer _}`
491
? "./"
492
: TTo;
493
494
type AbsoluteToPath<TRouter extends AnyRouter, TTo extends string> = TTo;
495
496
type RelativeToPath<
497
TRouter extends AnyRouter,
498
TFrom extends string,
499
TTo extends string
500
> = TTo extends "."
501
? TFrom
502
: TTo extends `..${infer Rest}`
503
? RelativeToParentPath<TRouter, TFrom, Rest>
504
: TTo extends `./${infer Rest}`
505
? RelativeToCurrentPath<TRouter, TFrom, Rest>
506
: never;
507
```