@tanstack/router-core 1.141.1 → 1.141.2

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.
@@ -643,6 +643,7 @@ export declare class RouterCore<in out TRouteTree extends AnyRoute, in out TTrai
643
643
  * on the next `load()` call (eg. after HMR or a manual invalidation).
644
644
  */
645
645
  invalidate: InvalidateFn<RouterCore<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>>;
646
+ getParsedLocationHref: (location: ParsedLocation) => string;
646
647
  resolveRedirect: (redirect: AnyRedirect) => AnyRedirect;
647
648
  clearCache: ClearCacheFn<this>;
648
649
  clearExpiredCache: () => void;
@@ -37,14 +37,14 @@ export interface ParsedLocation<TSearchObj extends AnySchema = {}> {
37
37
  unmaskOnReload?: boolean;
38
38
  /**
39
39
  * @private
40
- * @description The public href of the location, including the origin before any rewrites.
40
+ * @description The public href of the location.
41
41
  * If a rewrite is applied, the `href` property will be the rewritten URL.
42
42
  */
43
43
  publicHref: string;
44
44
  /**
45
45
  * @private
46
- * @description The full URL of the location, including the origin.
46
+ * @description The full URL of the location.
47
47
  * @private
48
48
  */
49
- url: string;
49
+ url: URL;
50
50
  }
@@ -643,6 +643,7 @@ export declare class RouterCore<in out TRouteTree extends AnyRoute, in out TTrai
643
643
  * on the next `load()` call (eg. after HMR or a manual invalidation).
644
644
  */
645
645
  invalidate: InvalidateFn<RouterCore<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TRouterHistory, TDehydrated>>;
646
+ getParsedLocationHref: (location: ParsedLocation) => string;
646
647
  resolveRedirect: (redirect: AnyRedirect) => AnyRedirect;
647
648
  clearCache: ClearCacheFn<this>;
648
649
  clearExpiredCache: () => void;
@@ -206,15 +206,14 @@ class RouterCore {
206
206
  const searchStr = this.options.stringifySearch(parsedSearch);
207
207
  url.search = searchStr;
208
208
  const fullPath = url.href.replace(url.origin, "");
209
- const { pathname, hash } = url;
210
209
  return {
211
210
  href: fullPath,
212
211
  publicHref: href,
213
- url: url.href,
214
- pathname: decodePath(pathname),
212
+ url,
213
+ pathname: decodePath(url.pathname),
215
214
  searchStr,
216
215
  search: replaceEqualDeep(previousLocation?.search, parsedSearch),
217
- hash: hash.split("#").reverse()[0] ?? "",
216
+ hash: url.hash.split("#").reverse()[0] ?? "",
218
217
  state: replaceEqualDeep(previousLocation?.state, state)
219
218
  };
220
219
  };
@@ -375,7 +374,7 @@ class RouterCore {
375
374
  return {
376
375
  publicHref: rewrittenUrl.pathname + rewrittenUrl.search + rewrittenUrl.hash,
377
376
  href: fullPath,
378
- url: rewrittenUrl.href,
377
+ url: rewrittenUrl,
379
378
  pathname: nextPathname,
380
379
  search: nextSearch,
381
380
  searchStr,
@@ -454,7 +453,16 @@ class RouterCore {
454
453
  if (isSameUrl && isSameState()) {
455
454
  this.load();
456
455
  } else {
457
- let { maskedLocation, hashScrollIntoView, ...nextHistory } = next;
456
+ let {
457
+ // eslint-disable-next-line prefer-const
458
+ maskedLocation,
459
+ // eslint-disable-next-line prefer-const
460
+ hashScrollIntoView,
461
+ // don't pass url into history since it is a URL instance that cannot be serialized
462
+ // eslint-disable-next-line prefer-const
463
+ url: _url,
464
+ ...nextHistory
465
+ } = next;
458
466
  if (maskedLocation) {
459
467
  nextHistory = {
460
468
  ...maskedLocation,
@@ -542,7 +550,7 @@ class RouterCore {
542
550
  if (reloadDocument) {
543
551
  if (!href) {
544
552
  const location = this.buildLocation({ to, ...rest });
545
- href = location.url;
553
+ href = location.url.href;
546
554
  }
547
555
  if (!rest.ignoreBlocker) {
548
556
  const historyWithBlockers = this.history;
@@ -587,18 +595,8 @@ class RouterCore {
587
595
  state: true,
588
596
  _includeValidateSearch: true
589
597
  });
590
- const normalizeUrl = (url) => {
591
- try {
592
- return encodeURI(decodeURI(url));
593
- } catch {
594
- return url;
595
- }
596
- };
597
- if (trimPath(normalizeUrl(this.latestLocation.href)) !== trimPath(normalizeUrl(nextLocation.href))) {
598
- let href = nextLocation.url;
599
- if (this.origin && href.startsWith(this.origin)) {
600
- href = href.replace(this.origin, "") || "/";
601
- }
598
+ if (this.latestLocation.publicHref !== nextLocation.publicHref || nextLocation.url.origin !== this.origin) {
599
+ const href = this.getParsedLocationHref(nextLocation);
602
600
  throw redirect({ href });
603
601
  }
604
602
  }
@@ -817,13 +815,17 @@ class RouterCore {
817
815
  this.shouldViewTransition = false;
818
816
  return this.load({ sync: opts?.sync });
819
817
  };
818
+ this.getParsedLocationHref = (location) => {
819
+ let href = location.url.href;
820
+ if (this.origin && location.url.origin === this.origin) {
821
+ href = href.replace(this.origin, "") || "/";
822
+ }
823
+ return href;
824
+ };
820
825
  this.resolveRedirect = (redirect2) => {
821
826
  if (!redirect2.options.href) {
822
827
  const location = this.buildLocation(redirect2.options);
823
- let href = location.url;
824
- if (this.origin && href.startsWith(this.origin)) {
825
- href = href.replace(this.origin, "") || "/";
826
- }
828
+ const href = this.getParsedLocationHref(location);
827
829
  redirect2.options.href = location.href;
828
830
  redirect2.headers.set("Location", href);
829
831
  }