@tanstack/react-router 1.132.0-alpha.4 → 1.132.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/cjs/Asset.cjs +32 -0
  2. package/dist/cjs/Asset.cjs.map +1 -1
  3. package/dist/cjs/ScriptOnce.cjs +5 -4
  4. package/dist/cjs/ScriptOnce.cjs.map +1 -1
  5. package/dist/cjs/ScriptOnce.d.cts +1 -3
  6. package/dist/cjs/fileRoute.cjs.map +1 -1
  7. package/dist/cjs/fileRoute.d.cts +3 -3
  8. package/dist/cjs/index.cjs +12 -4
  9. package/dist/cjs/index.cjs.map +1 -1
  10. package/dist/cjs/index.d.cts +7 -4
  11. package/dist/cjs/link.cjs +69 -71
  12. package/dist/cjs/link.cjs.map +1 -1
  13. package/dist/cjs/route.cjs +4 -1
  14. package/dist/cjs/route.cjs.map +1 -1
  15. package/dist/cjs/route.d.cts +11 -11
  16. package/dist/cjs/router.cjs.map +1 -1
  17. package/dist/cjs/router.d.cts +2 -2
  18. package/dist/cjs/ssr/renderRouterToString.cjs +1 -0
  19. package/dist/cjs/ssr/renderRouterToString.cjs.map +1 -1
  20. package/dist/cjs/ssr/serializer.d.cts +6 -0
  21. package/dist/cjs/typePrimitives.d.cts +6 -0
  22. package/dist/cjs/useBlocker.cjs +1 -1
  23. package/dist/cjs/useBlocker.cjs.map +1 -1
  24. package/dist/cjs/useNavigate.cjs +4 -11
  25. package/dist/cjs/useNavigate.cjs.map +1 -1
  26. package/dist/cjs/useParams.cjs +3 -2
  27. package/dist/cjs/useParams.cjs.map +1 -1
  28. package/dist/esm/Asset.js +32 -0
  29. package/dist/esm/Asset.js.map +1 -1
  30. package/dist/esm/ScriptOnce.d.ts +1 -3
  31. package/dist/esm/ScriptOnce.js +5 -4
  32. package/dist/esm/ScriptOnce.js.map +1 -1
  33. package/dist/esm/fileRoute.d.ts +3 -3
  34. package/dist/esm/fileRoute.js.map +1 -1
  35. package/dist/esm/index.d.ts +7 -4
  36. package/dist/esm/index.js +4 -2
  37. package/dist/esm/link.js +69 -71
  38. package/dist/esm/link.js.map +1 -1
  39. package/dist/esm/route.d.ts +11 -11
  40. package/dist/esm/route.js +4 -1
  41. package/dist/esm/route.js.map +1 -1
  42. package/dist/esm/router.d.ts +2 -2
  43. package/dist/esm/router.js.map +1 -1
  44. package/dist/esm/ssr/renderRouterToString.js +1 -0
  45. package/dist/esm/ssr/renderRouterToString.js.map +1 -1
  46. package/dist/esm/ssr/serializer.d.ts +6 -0
  47. package/dist/esm/typePrimitives.d.ts +6 -0
  48. package/dist/esm/useBlocker.js +1 -1
  49. package/dist/esm/useBlocker.js.map +1 -1
  50. package/dist/esm/useNavigate.js +4 -11
  51. package/dist/esm/useNavigate.js.map +1 -1
  52. package/dist/esm/useParams.js +3 -2
  53. package/dist/esm/useParams.js.map +1 -1
  54. package/dist/llms/rules/guide.d.ts +1 -1
  55. package/dist/llms/rules/guide.js +49 -10
  56. package/dist/llms/rules/routing.d.ts +1 -1
  57. package/dist/llms/rules/routing.js +2 -2
  58. package/dist/llms/rules/setup-and-architecture.d.ts +1 -1
  59. package/dist/llms/rules/setup-and-architecture.js +19 -19
  60. package/package.json +3 -3
  61. package/src/Asset.tsx +44 -0
  62. package/src/ScriptOnce.tsx +6 -8
  63. package/src/fileRoute.ts +17 -2
  64. package/src/index.tsx +9 -5
  65. package/src/link.tsx +75 -83
  66. package/src/route.tsx +114 -18
  67. package/src/router.ts +2 -5
  68. package/src/ssr/renderRouterToString.tsx +1 -0
  69. package/src/ssr/serializer.ts +7 -0
  70. package/src/typePrimitives.ts +1 -1
  71. package/src/useBlocker.tsx +1 -1
  72. package/src/useNavigate.tsx +4 -18
  73. package/src/useParams.tsx +5 -3
package/src/link.tsx CHANGED
@@ -12,7 +12,6 @@ import { useRouter } from './useRouter'
12
12
 
13
13
  import { useForwardedRef, useIntersectionObserver } from './utils'
14
14
 
15
- import { useMatch } from './useMatch'
16
15
  import type {
17
16
  AnyRouter,
18
17
  Constrain,
@@ -79,39 +78,24 @@ export function useLinkProps<
79
78
  ...propsSafeToSpread
80
79
  } = options
81
80
 
82
- // If this link simply reloads the current route,
83
- // make sure it has a new key so it will trigger a data refresh
84
-
85
- // If this `to` is a valid external URL, return
86
- // null for LinkUtils
87
-
88
- const type: 'internal' | 'external' = React.useMemo(() => {
89
- try {
90
- new URL(to as any)
91
- return 'external'
92
- } catch {}
93
- return 'internal'
94
- }, [to])
95
-
96
81
  // subscribe to search params to re-build location if it changes
97
82
  const currentSearch = useRouterState({
98
83
  select: (s) => s.location.search,
99
84
  structuralSharing: true as any,
100
85
  })
101
86
 
102
- const from = useMatch({
103
- strict: false,
104
- select: (match) => options.from ?? match.fullPath,
105
- })
87
+ const from = options.from
106
88
 
107
- const next = React.useMemo(
108
- () => router.buildLocation({ ...options, from } as any),
89
+ const _options = React.useMemo(
90
+ () => {
91
+ return { ...options, from }
92
+ },
109
93
  // eslint-disable-next-line react-hooks/exhaustive-deps
110
94
  [
111
95
  router,
112
96
  currentSearch,
113
- options._fromLocation,
114
97
  from,
98
+ options._fromLocation,
115
99
  options.hash,
116
100
  options.to,
117
101
  options.search,
@@ -122,10 +106,41 @@ export function useLinkProps<
122
106
  ],
123
107
  )
124
108
 
125
- const isExternal = type === 'external'
109
+ const next = React.useMemo(
110
+ () => router.buildLocation({ ..._options } as any),
111
+ [router, _options],
112
+ )
113
+
114
+ const hrefOption = React.useMemo(() => {
115
+ if (disabled) {
116
+ return undefined
117
+ }
118
+ let href = next.maskedLocation ? next.maskedLocation.url : next.url
119
+
120
+ let external = false
121
+ if (router.origin) {
122
+ if (href.startsWith(router.origin)) {
123
+ href = href.replace(router.origin, '') || '/'
124
+ } else {
125
+ external = true
126
+ }
127
+ }
128
+ return { href, external }
129
+ }, [disabled, next.maskedLocation, next.url, router.origin])
130
+
131
+ const externalLink = React.useMemo(() => {
132
+ if (hrefOption?.external) {
133
+ return hrefOption.href
134
+ }
135
+ try {
136
+ new URL(to as any)
137
+ return to
138
+ } catch {}
139
+ return undefined
140
+ }, [to, hrefOption])
126
141
 
127
142
  const preload =
128
- options.reloadDocument || isExternal
143
+ options.reloadDocument || externalLink
129
144
  ? false
130
145
  : (userPreload ?? router.options.defaultPreload)
131
146
  const preloadDelay =
@@ -133,7 +148,7 @@ export function useLinkProps<
133
148
 
134
149
  const isActive = useRouterState({
135
150
  select: (s) => {
136
- if (isExternal) return false
151
+ if (externalLink) return false
137
152
  if (activeOptions?.exact) {
138
153
  const testExact = exactPathTest(
139
154
  s.location.pathname,
@@ -180,34 +195,12 @@ export function useLinkProps<
180
195
  },
181
196
  })
182
197
 
183
- const doPreload = React.useCallback(
184
- () => {
185
- router.preloadRoute({ ...options, from } as any).catch((err) => {
186
- console.warn(err)
187
- console.warn(preloadWarning)
188
- })
189
- },
190
- // eslint-disable-next-line react-hooks/exhaustive-deps
191
- [
192
- router,
193
- options.to,
194
- options._fromLocation,
195
- from,
196
- options.search,
197
- options.hash,
198
- options.params,
199
- options.state,
200
- options.mask,
201
- options.unsafeRelative,
202
- options.hashScrollIntoView,
203
- options.href,
204
- options.ignoreBlocker,
205
- options.reloadDocument,
206
- options.replace,
207
- options.resetScroll,
208
- options.viewTransition,
209
- ],
210
- )
198
+ const doPreload = React.useCallback(() => {
199
+ router.preloadRoute({ ..._options } as any).catch((err) => {
200
+ console.warn(err)
201
+ console.warn(preloadWarning)
202
+ })
203
+ }, [router, _options])
211
204
 
212
205
  const preloadViewportIoCallback = React.useCallback(
213
206
  (entry: IntersectionObserverEntry | undefined) => {
@@ -235,32 +228,17 @@ export function useLinkProps<
235
228
  }
236
229
  }, [disabled, doPreload, preload])
237
230
 
238
- if (isExternal) {
239
- return {
240
- ...propsSafeToSpread,
241
- ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],
242
- type,
243
- href: to,
244
- ...(children && { children }),
245
- ...(target && { target }),
246
- ...(disabled && { disabled }),
247
- ...(style && { style }),
248
- ...(className && { className }),
249
- ...(onClick && { onClick }),
250
- ...(onFocus && { onFocus }),
251
- ...(onMouseEnter && { onMouseEnter }),
252
- ...(onMouseLeave && { onMouseLeave }),
253
- ...(onTouchStart && { onTouchStart }),
254
- }
255
- }
256
-
257
231
  // The click handler
258
232
  const handleClick = (e: React.MouseEvent) => {
233
+ // Check actual element's target attribute as fallback
234
+ const elementTarget = (e.currentTarget as HTMLAnchorElement).target
235
+ const effectiveTarget = target !== undefined ? target : elementTarget
236
+
259
237
  if (
260
238
  !disabled &&
261
239
  !isCtrlEvent(e) &&
262
240
  !e.defaultPrevented &&
263
- (!target || target === '_self') &&
241
+ (!effectiveTarget || effectiveTarget === '_self') &&
264
242
  e.button === 0
265
243
  ) {
266
244
  e.preventDefault()
@@ -277,8 +255,7 @@ export function useLinkProps<
277
255
  // All is well? Navigate!
278
256
  // N.B. we don't call `router.commitLocation(next) here because we want to run `validateSearch` before committing
279
257
  router.navigate({
280
- ...options,
281
- from,
258
+ ..._options,
282
259
  replace,
283
260
  resetScroll,
284
261
  hashScrollIntoView,
@@ -289,6 +266,24 @@ export function useLinkProps<
289
266
  }
290
267
  }
291
268
 
269
+ if (externalLink) {
270
+ return {
271
+ ...propsSafeToSpread,
272
+ ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],
273
+ href: externalLink,
274
+ ...(children && { children }),
275
+ ...(target && { target }),
276
+ ...(disabled && { disabled }),
277
+ ...(style && { style }),
278
+ ...(className && { className }),
279
+ ...(onClick && { onClick }),
280
+ ...(onFocus && { onFocus }),
281
+ ...(onMouseEnter && { onMouseEnter }),
282
+ ...(onMouseLeave && { onMouseLeave }),
283
+ ...(onTouchStart && { onTouchStart }),
284
+ }
285
+ }
286
+
292
287
  // The click handler
293
288
  const handleFocus = (_: React.MouseEvent) => {
294
289
  if (disabled) return
@@ -358,11 +353,7 @@ export function useLinkProps<
358
353
  ...propsSafeToSpread,
359
354
  ...resolvedActiveProps,
360
355
  ...resolvedInactiveProps,
361
- href: disabled
362
- ? undefined
363
- : next.maskedLocation
364
- ? router.history.createHref(next.maskedLocation.href)
365
- : router.history.createHref(next.href),
356
+ href: hrefOption?.href,
366
357
  ref: innerRef as React.ComponentPropsWithRef<'a'>['ref'],
367
358
  onClick: composeHandlers([onClick, handleClick]),
368
359
  onFocus: composeHandlers([onFocus, handleFocus]),
@@ -394,10 +385,11 @@ const intersectionObserverOptions: IntersectionObserverInit = {
394
385
  const composeHandlers =
395
386
  (handlers: Array<undefined | React.EventHandler<any>>) =>
396
387
  (e: React.SyntheticEvent) => {
397
- handlers.filter(Boolean).forEach((handler) => {
388
+ for (const handler of handlers) {
389
+ if (!handler) continue
398
390
  if (e.defaultPrevented) return
399
- handler!(e)
400
- })
391
+ handler(e)
392
+ }
401
393
  }
402
394
 
403
395
  type UseLinkReactProps<TComp> = TComp extends keyof React.JSX.IntrinsicElements
package/src/route.tsx CHANGED
@@ -21,6 +21,7 @@ import type {
21
21
  ErrorComponentProps,
22
22
  NotFoundError,
23
23
  NotFoundRouteProps,
24
+ Register,
24
25
  RegisteredRouter,
25
26
  ResolveFullPath,
26
27
  ResolveId,
@@ -158,6 +159,7 @@ export class RouteApi<
158
159
  }
159
160
 
160
161
  export class Route<
162
+ in out TRegister = unknown,
161
163
  in out TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute,
162
164
  in out TPath extends RouteConstraints['TPath'] = '/',
163
165
  in out TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<
@@ -179,8 +181,12 @@ export class Route<
179
181
  in out TLoaderFn = undefined,
180
182
  in out TChildren = unknown,
181
183
  in out TFileRouteTypes = unknown,
184
+ in out TSSR = unknown,
185
+ in out TServerMiddlewares = unknown,
186
+ in out THandlers = undefined,
182
187
  >
183
188
  extends BaseRoute<
189
+ TRegister,
184
190
  TParentRoute,
185
191
  TPath,
186
192
  TFullPath,
@@ -194,10 +200,14 @@ export class Route<
194
200
  TLoaderDeps,
195
201
  TLoaderFn,
196
202
  TChildren,
197
- TFileRouteTypes
203
+ TFileRouteTypes,
204
+ TSSR,
205
+ TServerMiddlewares,
206
+ THandlers
198
207
  >
199
208
  implements
200
209
  RouteCore<
210
+ TRegister,
201
211
  TParentRoute,
202
212
  TPath,
203
213
  TFullPath,
@@ -211,7 +221,10 @@ export class Route<
211
221
  TLoaderDeps,
212
222
  TLoaderFn,
213
223
  TChildren,
214
- TFileRouteTypes
224
+ TFileRouteTypes,
225
+ TSSR,
226
+ TServerMiddlewares,
227
+ THandlers
215
228
  >
216
229
  {
217
230
  /**
@@ -219,6 +232,7 @@ export class Route<
219
232
  */
220
233
  constructor(
221
234
  options?: RouteOptions<
235
+ TRegister,
222
236
  TParentRoute,
223
237
  TId,
224
238
  TCustomId,
@@ -230,7 +244,10 @@ export class Route<
230
244
  TLoaderFn,
231
245
  TRouterContext,
232
246
  TRouteContextFn,
233
- TBeforeLoadFn
247
+ TBeforeLoadFn,
248
+ TSSR,
249
+ TServerMiddlewares,
250
+ THandlers
234
251
  >,
235
252
  ) {
236
253
  super(options)
@@ -291,6 +308,7 @@ export class Route<
291
308
  }
292
309
 
293
310
  export function createRoute<
311
+ TRegister = unknown,
294
312
  TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute,
295
313
  TPath extends RouteConstraints['TPath'] = '/',
296
314
  TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<
@@ -310,8 +328,11 @@ export function createRoute<
310
328
  TLoaderDeps extends Record<string, any> = {},
311
329
  TLoaderFn = undefined,
312
330
  TChildren = unknown,
331
+ TSSR = unknown,
332
+ const TServerMiddlewares = unknown,
313
333
  >(
314
334
  options: RouteOptions<
335
+ TRegister,
315
336
  TParentRoute,
316
337
  TId,
317
338
  TCustomId,
@@ -323,9 +344,12 @@ export function createRoute<
323
344
  TLoaderFn,
324
345
  AnyContext,
325
346
  TRouteContextFn,
326
- TBeforeLoadFn
347
+ TBeforeLoadFn,
348
+ TSSR,
349
+ TServerMiddlewares
327
350
  >,
328
351
  ): Route<
352
+ TRegister,
329
353
  TParentRoute,
330
354
  TPath,
331
355
  TFullPath,
@@ -338,9 +362,12 @@ export function createRoute<
338
362
  TBeforeLoadFn,
339
363
  TLoaderDeps,
340
364
  TLoaderFn,
341
- TChildren
365
+ TChildren,
366
+ TSSR,
367
+ TServerMiddlewares
342
368
  > {
343
369
  return new Route<
370
+ TRegister,
344
371
  TParentRoute,
345
372
  TPath,
346
373
  TFullPath,
@@ -353,36 +380,62 @@ export function createRoute<
353
380
  TBeforeLoadFn,
354
381
  TLoaderDeps,
355
382
  TLoaderFn,
356
- TChildren
357
- >(options)
383
+ TChildren,
384
+ TSSR,
385
+ TServerMiddlewares
386
+ >(
387
+ // TODO: Help us TypeChris, you're our only hope!
388
+ options as any,
389
+ )
358
390
  }
359
391
 
360
- export type AnyRootRoute = RootRoute<any, any, any, any, any, any, any, any>
392
+ export type AnyRootRoute = RootRoute<
393
+ any,
394
+ any,
395
+ any,
396
+ any,
397
+ any,
398
+ any,
399
+ any,
400
+ any,
401
+ any,
402
+ any,
403
+ any
404
+ >
361
405
 
362
406
  export function createRootRouteWithContext<TRouterContext extends {}>() {
363
407
  return <
408
+ TRegister = Register,
364
409
  TRouteContextFn = AnyContext,
365
410
  TBeforeLoadFn = AnyContext,
366
411
  TSearchValidator = undefined,
367
412
  TLoaderDeps extends Record<string, any> = {},
368
413
  TLoaderFn = undefined,
414
+ TSSR = unknown,
415
+ TServerMiddlewares = unknown,
369
416
  >(
370
417
  options?: RootRouteOptions<
418
+ TRegister,
371
419
  TSearchValidator,
372
420
  TRouterContext,
373
421
  TRouteContextFn,
374
422
  TBeforeLoadFn,
375
423
  TLoaderDeps,
376
- TLoaderFn
424
+ TLoaderFn,
425
+ TSSR,
426
+ TServerMiddlewares
377
427
  >,
378
428
  ) => {
379
429
  return createRootRoute<
430
+ TRegister,
380
431
  TSearchValidator,
381
432
  TRouterContext,
382
433
  TRouteContextFn,
383
434
  TBeforeLoadFn,
384
435
  TLoaderDeps,
385
- TLoaderFn
436
+ TLoaderFn,
437
+ TSSR,
438
+ TServerMiddlewares
386
439
  >(options as any)
387
440
  }
388
441
  }
@@ -393,6 +446,7 @@ export function createRootRouteWithContext<TRouterContext extends {}>() {
393
446
  export const rootRouteWithContext = createRootRouteWithContext
394
447
 
395
448
  export class RootRoute<
449
+ in out TRegister = unknown,
396
450
  in out TSearchValidator = undefined,
397
451
  in out TRouterContext = {},
398
452
  in out TRouteContextFn = AnyContext,
@@ -401,8 +455,12 @@ export class RootRoute<
401
455
  in out TLoaderFn = undefined,
402
456
  in out TChildren = unknown,
403
457
  in out TFileRouteTypes = unknown,
458
+ in out TSSR = unknown,
459
+ in out TServerMiddlewares = unknown,
460
+ in out THandlers = undefined,
404
461
  >
405
462
  extends BaseRootRoute<
463
+ TRegister,
406
464
  TSearchValidator,
407
465
  TRouterContext,
408
466
  TRouteContextFn,
@@ -410,10 +468,14 @@ export class RootRoute<
410
468
  TLoaderDeps,
411
469
  TLoaderFn,
412
470
  TChildren,
413
- TFileRouteTypes
471
+ TFileRouteTypes,
472
+ TSSR,
473
+ TServerMiddlewares,
474
+ THandlers
414
475
  >
415
476
  implements
416
477
  RootRouteCore<
478
+ TRegister,
417
479
  TSearchValidator,
418
480
  TRouterContext,
419
481
  TRouteContextFn,
@@ -421,7 +483,10 @@ export class RootRoute<
421
483
  TLoaderDeps,
422
484
  TLoaderFn,
423
485
  TChildren,
424
- TFileRouteTypes
486
+ TFileRouteTypes,
487
+ TSSR,
488
+ TServerMiddlewares,
489
+ THandlers
425
490
  >
426
491
  {
427
492
  /**
@@ -429,12 +494,16 @@ export class RootRoute<
429
494
  */
430
495
  constructor(
431
496
  options?: RootRouteOptions<
497
+ TRegister,
432
498
  TSearchValidator,
433
499
  TRouterContext,
434
500
  TRouteContextFn,
435
501
  TBeforeLoadFn,
436
502
  TLoaderDeps,
437
- TLoaderFn
503
+ TLoaderFn,
504
+ TSSR,
505
+ TServerMiddlewares,
506
+ THandlers
438
507
  >,
439
508
  ) {
440
509
  super(options)
@@ -495,22 +564,31 @@ export class RootRoute<
495
564
  }
496
565
 
497
566
  export function createRootRoute<
567
+ TRegister = Register,
498
568
  TSearchValidator = undefined,
499
569
  TRouterContext = {},
500
570
  TRouteContextFn = AnyContext,
501
571
  TBeforeLoadFn = AnyContext,
502
572
  TLoaderDeps extends Record<string, any> = {},
503
573
  TLoaderFn = undefined,
574
+ TSSR = unknown,
575
+ const TServerMiddlewares = unknown,
576
+ THandlers = undefined,
504
577
  >(
505
578
  options?: RootRouteOptions<
579
+ TRegister,
506
580
  TSearchValidator,
507
581
  TRouterContext,
508
582
  TRouteContextFn,
509
583
  TBeforeLoadFn,
510
584
  TLoaderDeps,
511
- TLoaderFn
585
+ TLoaderFn,
586
+ TSSR,
587
+ TServerMiddlewares,
588
+ THandlers
512
589
  >,
513
590
  ): RootRoute<
591
+ TRegister,
514
592
  TSearchValidator,
515
593
  TRouterContext,
516
594
  TRouteContextFn,
@@ -518,15 +596,24 @@ export function createRootRoute<
518
596
  TLoaderDeps,
519
597
  TLoaderFn,
520
598
  unknown,
521
- unknown
599
+ unknown,
600
+ TSSR,
601
+ TServerMiddlewares,
602
+ THandlers
522
603
  > {
523
604
  return new RootRoute<
605
+ TRegister,
524
606
  TSearchValidator,
525
607
  TRouterContext,
526
608
  TRouteContextFn,
527
609
  TBeforeLoadFn,
528
610
  TLoaderDeps,
529
- TLoaderFn
611
+ TLoaderFn,
612
+ unknown,
613
+ unknown,
614
+ TSSR,
615
+ TServerMiddlewares,
616
+ THandlers
530
617
  >(options)
531
618
  }
532
619
 
@@ -560,6 +647,7 @@ export type ErrorRouteComponent = AsyncRouteComponent<ErrorComponentProps>
560
647
  export type NotFoundRouteComponent = RouteTypes<NotFoundRouteProps>['component']
561
648
 
562
649
  export class NotFoundRoute<
650
+ TRegister,
563
651
  TParentRoute extends AnyRootRoute,
564
652
  TRouterContext = AnyContext,
565
653
  TRouteContextFn = AnyContext,
@@ -568,7 +656,10 @@ export class NotFoundRoute<
568
656
  TLoaderDeps extends Record<string, any> = {},
569
657
  TLoaderFn = undefined,
570
658
  TChildren = unknown,
659
+ TSSR = unknown,
660
+ TServerMiddlewares = unknown,
571
661
  > extends Route<
662
+ TRegister,
572
663
  TParentRoute,
573
664
  '/404',
574
665
  '/404',
@@ -581,11 +672,14 @@ export class NotFoundRoute<
581
672
  TBeforeLoadFn,
582
673
  TLoaderDeps,
583
674
  TLoaderFn,
584
- TChildren
675
+ TChildren,
676
+ TSSR,
677
+ TServerMiddlewares
585
678
  > {
586
679
  constructor(
587
680
  options: Omit<
588
681
  RouteOptions<
682
+ TRegister,
589
683
  TParentRoute,
590
684
  string,
591
685
  string,
@@ -597,7 +691,9 @@ export class NotFoundRoute<
597
691
  TLoaderFn,
598
692
  TRouterContext,
599
693
  TRouteContextFn,
600
- TBeforeLoadFn
694
+ TBeforeLoadFn,
695
+ TSSR,
696
+ TServerMiddlewares
601
697
  >,
602
698
  | 'caseSensitive'
603
699
  | 'parseParams'
package/src/router.ts CHANGED
@@ -87,14 +87,12 @@ export class Router<
87
87
  in out TDefaultStructuralSharingOption extends boolean = false,
88
88
  in out TRouterHistory extends RouterHistory = RouterHistory,
89
89
  in out TDehydrated extends Record<string, any> = Record<string, any>,
90
- in out TTransformerConfig = any,
91
90
  > extends RouterCore<
92
91
  TRouteTree,
93
92
  TTrailingSlashOption,
94
93
  TDefaultStructuralSharingOption,
95
94
  TRouterHistory,
96
- TDehydrated,
97
- TTransformerConfig
95
+ TDehydrated
98
96
  > {
99
97
  constructor(
100
98
  options: RouterConstructorOptions<
@@ -102,8 +100,7 @@ export class Router<
102
100
  TTrailingSlashOption,
103
101
  TDefaultStructuralSharingOption,
104
102
  TRouterHistory,
105
- TDehydrated,
106
- TTransformerConfig
103
+ TDehydrated
107
104
  >,
108
105
  ) {
109
106
  super(options)
@@ -13,6 +13,7 @@ export const renderRouterToString = async ({
13
13
  }) => {
14
14
  try {
15
15
  let html = ReactDOMServer.renderToString(children)
16
+ router.serverSsr!.setRenderFinished()
16
17
  const injectedHtml = await Promise.all(router.serverSsr!.injectedHtml).then(
17
18
  (htmls) => htmls.join(''),
18
19
  )
@@ -0,0 +1,7 @@
1
+ import type * as React from 'react'
2
+
3
+ declare module '@tanstack/router-core' {
4
+ export interface SerializerExtensions {
5
+ ReadableStream: React.JSX.Element
6
+ }
7
+ }
@@ -32,7 +32,7 @@ export type ValidateLinkOptions<
32
32
  >
33
33
 
34
34
  /**
35
- * @internal
35
+ * @private
36
36
  */
37
37
  export type InferStructuralSharing<TOptions> = TOptions extends {
38
38
  structuralSharing: infer TStructuralSharing
@@ -176,7 +176,7 @@ export function useBlocker(
176
176
  function getLocation(
177
177
  location: HistoryLocation,
178
178
  ): AnyShouldBlockFnLocation {
179
- const parsedLocation = router.parseLocation(undefined, location)
179
+ const parsedLocation = router.parseLocation(location)
180
180
  const matchedRoutes = router.getMatchedRoutes(
181
181
  parsedLocation.pathname,
182
182
  undefined,
@@ -1,6 +1,5 @@
1
1
  import * as React from 'react'
2
2
  import { useRouter } from './useRouter'
3
- import { useMatch } from './useMatch'
4
3
  import type {
5
4
  AnyRouter,
6
5
  FromPathOption,
@@ -15,29 +14,16 @@ export function useNavigate<
15
14
  >(_defaultOpts?: {
16
15
  from?: FromPathOption<TRouter, TDefaultFrom>
17
16
  }): UseNavigateResult<TDefaultFrom> {
18
- const { navigate, state } = useRouter()
19
-
20
- // Just get the index of the current match to avoid rerenders
21
- // as much as possible
22
- const matchIndex = useMatch({
23
- strict: false,
24
- select: (match) => match.index,
25
- })
17
+ const router = useRouter()
26
18
 
27
19
  return React.useCallback(
28
20
  (options: NavigateOptions) => {
29
- const from =
30
- options.from ??
31
- _defaultOpts?.from ??
32
- state.matches[matchIndex]!.fullPath
33
-
34
- return navigate({
21
+ return router.navigate({
35
22
  ...options,
36
- from,
23
+ from: options.from ?? _defaultOpts?.from,
37
24
  })
38
25
  },
39
- // eslint-disable-next-line react-hooks/exhaustive-deps
40
- [_defaultOpts?.from, navigate],
26
+ [_defaultOpts?.from, router],
41
27
  ) as UseNavigateResult<TDefaultFrom>
42
28
  }
43
29