@tanstack/vue-router 1.141.2 → 1.141.6

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 (56) hide show
  1. package/dist/esm/CatchBoundary.d.ts +4 -2
  2. package/dist/esm/CatchBoundary.js +29 -28
  3. package/dist/esm/CatchBoundary.js.map +1 -1
  4. package/dist/esm/ClientOnly.js +33 -0
  5. package/dist/esm/ClientOnly.js.map +1 -0
  6. package/dist/esm/Match.js +66 -39
  7. package/dist/esm/Match.js.map +1 -1
  8. package/dist/esm/ScriptOnce.js +1 -3
  9. package/dist/esm/ScriptOnce.js.map +1 -1
  10. package/dist/esm/Scripts.js +0 -9
  11. package/dist/esm/Scripts.js.map +1 -1
  12. package/dist/esm/Transitioner.js +20 -6
  13. package/dist/esm/Transitioner.js.map +1 -1
  14. package/dist/esm/index.d.ts +2 -1
  15. package/dist/esm/index.js +2 -0
  16. package/dist/esm/index.js.map +1 -1
  17. package/dist/esm/lazyRouteComponent.d.ts +0 -6
  18. package/dist/esm/lazyRouteComponent.js +5 -24
  19. package/dist/esm/lazyRouteComponent.js.map +1 -1
  20. package/dist/esm/link.d.ts +4 -0
  21. package/dist/esm/link.js.map +1 -1
  22. package/dist/esm/route.d.ts +6 -1
  23. package/dist/esm/route.js +25 -0
  24. package/dist/esm/route.js.map +1 -1
  25. package/dist/source/CatchBoundary.d.ts +4 -2
  26. package/dist/source/CatchBoundary.jsx +23 -22
  27. package/dist/source/CatchBoundary.jsx.map +1 -1
  28. package/dist/source/Match.jsx +90 -63
  29. package/dist/source/Match.jsx.map +1 -1
  30. package/dist/source/ScriptOnce.jsx +2 -2
  31. package/dist/source/ScriptOnce.jsx.map +1 -1
  32. package/dist/source/Scripts.jsx +0 -9
  33. package/dist/source/Scripts.jsx.map +1 -1
  34. package/dist/source/Transitioner.jsx +23 -16
  35. package/dist/source/Transitioner.jsx.map +1 -1
  36. package/dist/source/index.d.ts +2 -1
  37. package/dist/source/index.jsx +1 -0
  38. package/dist/source/index.jsx.map +1 -1
  39. package/dist/source/lazyRouteComponent.d.ts +0 -6
  40. package/dist/source/lazyRouteComponent.jsx +3 -23
  41. package/dist/source/lazyRouteComponent.jsx.map +1 -1
  42. package/dist/source/link.d.ts +4 -0
  43. package/dist/source/link.jsx.map +1 -1
  44. package/dist/source/route.d.ts +6 -1
  45. package/dist/source/route.js +13 -0
  46. package/dist/source/route.js.map +1 -1
  47. package/package.json +2 -2
  48. package/src/CatchBoundary.tsx +35 -32
  49. package/src/Match.tsx +115 -73
  50. package/src/ScriptOnce.tsx +1 -3
  51. package/src/Scripts.tsx +0 -11
  52. package/src/Transitioner.tsx +31 -17
  53. package/src/index.tsx +2 -0
  54. package/src/lazyRouteComponent.tsx +10 -32
  55. package/src/link.tsx +20 -0
  56. package/src/route.ts +33 -1
@@ -1,11 +1,12 @@
1
1
  import { ErrorRouteComponent } from './route.js';
2
2
  import * as Vue from 'vue';
3
- export declare function CatchBoundary(props: {
3
+ type CatchBoundaryProps = {
4
4
  getResetKey: () => number | string;
5
5
  children: Vue.VNode;
6
6
  errorComponent?: ErrorRouteComponent | Vue.Component;
7
7
  onCatch?: (error: Error) => void;
8
- }): Vue.VNode<Vue.RendererNode, Vue.RendererElement, {
8
+ };
9
+ export declare function CatchBoundary(props: CatchBoundaryProps): Vue.VNode<Vue.RendererNode, Vue.RendererElement, {
9
10
  [key: string]: any;
10
11
  }>;
11
12
  export declare const ErrorComponent: Vue.DefineComponent<Vue.ExtractPropTypes<{
@@ -17,3 +18,4 @@ export declare const ErrorComponent: Vue.DefineComponent<Vue.ExtractPropTypes<{
17
18
  error: ObjectConstructor;
18
19
  reset: FunctionConstructor;
19
20
  }>> & Readonly<{}>, {}, {}, {}, {}, string, Vue.ComponentProvideOptions, true, {}, any>;
21
+ export {};
@@ -43,38 +43,39 @@ const VueErrorBoundary = Vue.defineComponent({
43
43
  };
44
44
  }
45
45
  });
46
- function CatchBoundary(props) {
47
- const CatchBoundaryWrapper = Vue.defineComponent({
48
- name: "CatchBoundaryWrapper",
49
- inheritAttrs: false,
50
- setup() {
51
- const resetKey = Vue.computed(() => props.getResetKey());
52
- return () => {
53
- return Vue.h(VueErrorBoundary, {
54
- resetKey: resetKey.value,
55
- onError: props.onCatch
56
- }, {
57
- default: () => props.children,
58
- fallback: ({
59
- error,
60
- reset
61
- }) => {
62
- if (props.errorComponent) {
63
- return Vue.h(props.errorComponent, {
64
- error,
65
- reset
66
- });
67
- }
68
- return Vue.h(ErrorComponent, {
46
+ const CatchBoundaryWrapper = Vue.defineComponent({
47
+ name: "CatchBoundary",
48
+ inheritAttrs: false,
49
+ props: ["getResetKey", "children", "errorComponent", "onCatch"],
50
+ setup(props) {
51
+ const resetKey = Vue.computed(() => props.getResetKey());
52
+ return () => {
53
+ return Vue.h(VueErrorBoundary, {
54
+ resetKey: resetKey.value,
55
+ onError: props.onCatch
56
+ }, {
57
+ default: () => props.children,
58
+ fallback: ({
59
+ error,
60
+ reset
61
+ }) => {
62
+ if (props.errorComponent) {
63
+ return Vue.h(props.errorComponent, {
69
64
  error,
70
65
  reset
71
66
  });
72
67
  }
73
- });
74
- };
75
- }
76
- });
77
- return Vue.h(CatchBoundaryWrapper);
68
+ return Vue.h(ErrorComponent, {
69
+ error,
70
+ reset
71
+ });
72
+ }
73
+ });
74
+ };
75
+ }
76
+ });
77
+ function CatchBoundary(props) {
78
+ return Vue.h(CatchBoundaryWrapper, props);
78
79
  }
79
80
  const ErrorComponent = Vue.defineComponent({
80
81
  name: "ErrorComponent",
@@ -1 +1 @@
1
- {"version":3,"file":"CatchBoundary.js","sources":["../../src/CatchBoundary.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport type { ErrorRouteComponent } from './route'\n\ninterface ErrorComponentProps {\n error: Error\n reset: () => void\n}\n\nconst VueErrorBoundary = Vue.defineComponent({\n name: 'VueErrorBoundary',\n props: {\n onError: Function,\n resetKey: [String, Number],\n },\n emits: ['catch'],\n setup(props, { slots }) {\n const error = Vue.ref<Error | null>(null)\n const resetFn = Vue.ref<(() => void) | null>(null)\n\n const reset = () => {\n error.value = null\n }\n\n Vue.watch(\n () => props.resetKey,\n (newKey, oldKey) => {\n if (newKey !== oldKey && error.value) {\n reset()\n }\n },\n )\n\n Vue.onErrorCaptured((err: Error) => {\n if (\n err instanceof Promise ||\n (err && typeof (err as any).then === 'function')\n ) {\n return false\n }\n\n error.value = err\n resetFn.value = reset\n\n if (props.onError) {\n props.onError(err)\n }\n\n return false\n })\n\n return () => {\n if (error.value && slots.fallback) {\n const fallbackContent = slots.fallback({\n error: error.value,\n reset,\n })\n return Array.isArray(fallbackContent) && fallbackContent.length === 1\n ? fallbackContent[0]\n : fallbackContent\n }\n\n const defaultContent = slots.default && slots.default()\n return Array.isArray(defaultContent) && defaultContent.length === 1\n ? defaultContent[0]\n : defaultContent\n }\n },\n})\n\nexport function CatchBoundary(props: {\n getResetKey: () => number | string\n children: Vue.VNode\n errorComponent?: ErrorRouteComponent | Vue.Component\n onCatch?: (error: Error) => void\n}) {\n const CatchBoundaryWrapper = Vue.defineComponent({\n name: 'CatchBoundaryWrapper',\n inheritAttrs: false,\n setup() {\n const resetKey = Vue.computed(() => props.getResetKey())\n\n return () => {\n return Vue.h(\n VueErrorBoundary,\n {\n resetKey: resetKey.value,\n onError: props.onCatch,\n },\n {\n default: () => props.children,\n fallback: ({ error, reset }: ErrorComponentProps) => {\n if (props.errorComponent) {\n return Vue.h(props.errorComponent, { error, reset })\n }\n return Vue.h(ErrorComponent, { error, reset })\n },\n },\n )\n }\n },\n })\n\n return Vue.h(CatchBoundaryWrapper)\n}\n\nexport const ErrorComponent = Vue.defineComponent({\n name: 'ErrorComponent',\n props: {\n error: Object,\n reset: Function,\n },\n setup(props) {\n const show = Vue.ref(process.env.NODE_ENV !== 'production')\n\n const toggleShow = () => {\n show.value = !show.value\n }\n\n return () =>\n Vue.h('div', { style: { padding: '.5rem', maxWidth: '100%' } }, [\n Vue.h(\n 'div',\n { style: { display: 'flex', alignItems: 'center', gap: '.5rem' } },\n [\n Vue.h(\n 'strong',\n { style: { fontSize: '1rem' } },\n 'Something went wrong!',\n ),\n Vue.h(\n 'button',\n {\n style: {\n appearance: 'none',\n fontSize: '.6em',\n border: '1px solid currentColor',\n padding: '.1rem .2rem',\n fontWeight: 'bold',\n borderRadius: '.25rem',\n },\n onClick: toggleShow,\n },\n show.value ? 'Hide Error' : 'Show Error',\n ),\n ],\n ),\n Vue.h('div', { style: { height: '.25rem' } }),\n show.value\n ? Vue.h('div', {}, [\n Vue.h(\n 'pre',\n {\n style: {\n fontSize: '.7em',\n border: '1px solid red',\n borderRadius: '.25rem',\n padding: '.3rem',\n color: 'red',\n overflow: 'auto',\n },\n },\n [\n props.error?.message\n ? Vue.h('code', {}, props.error.message)\n : null,\n ],\n ),\n ])\n : null,\n ])\n },\n})\n"],"names":["VueErrorBoundary","Vue","defineComponent","name","props","onError","Function","resetKey","String","Number","emits","setup","slots","error","ref","resetFn","reset","value","watch","newKey","oldKey","onErrorCaptured","err","Promise","then","fallback","fallbackContent","Array","isArray","length","defaultContent","default","CatchBoundary","CatchBoundaryWrapper","inheritAttrs","computed","getResetKey","h","onCatch","children","errorComponent","ErrorComponent","Object","show","process","env","NODE_ENV","toggleShow","style","padding","maxWidth","display","alignItems","gap","fontSize","appearance","border","fontWeight","borderRadius","onClick","height","color","overflow","message"],"mappings":"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"}
1
+ {"version":3,"file":"CatchBoundary.js","sources":["../../src/CatchBoundary.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport type { ErrorRouteComponent } from './route'\n\ninterface ErrorComponentProps {\n error: Error\n reset: () => void\n}\n\ntype CatchBoundaryProps = {\n getResetKey: () => number | string\n children: Vue.VNode\n errorComponent?: ErrorRouteComponent | Vue.Component\n onCatch?: (error: Error) => void\n}\n\nconst VueErrorBoundary = Vue.defineComponent({\n name: 'VueErrorBoundary',\n props: {\n onError: Function,\n resetKey: [String, Number],\n },\n emits: ['catch'],\n setup(props, { slots }) {\n const error = Vue.ref<Error | null>(null)\n const resetFn = Vue.ref<(() => void) | null>(null)\n\n const reset = () => {\n error.value = null\n }\n\n Vue.watch(\n () => props.resetKey,\n (newKey, oldKey) => {\n if (newKey !== oldKey && error.value) {\n reset()\n }\n },\n )\n\n Vue.onErrorCaptured((err: Error) => {\n if (\n err instanceof Promise ||\n (err && typeof (err as any).then === 'function')\n ) {\n return false\n }\n\n error.value = err\n resetFn.value = reset\n\n if (props.onError) {\n props.onError(err)\n }\n\n return false\n })\n\n return () => {\n if (error.value && slots.fallback) {\n const fallbackContent = slots.fallback({\n error: error.value,\n reset,\n })\n return Array.isArray(fallbackContent) && fallbackContent.length === 1\n ? fallbackContent[0]\n : fallbackContent\n }\n\n const defaultContent = slots.default && slots.default()\n return Array.isArray(defaultContent) && defaultContent.length === 1\n ? defaultContent[0]\n : defaultContent\n }\n },\n})\n\nconst CatchBoundaryWrapper = Vue.defineComponent({\n name: 'CatchBoundary',\n inheritAttrs: false,\n props: ['getResetKey', 'children', 'errorComponent', 'onCatch'] as any,\n setup(props: CatchBoundaryProps) {\n const resetKey = Vue.computed(() => props.getResetKey())\n\n return () => {\n return Vue.h(\n VueErrorBoundary,\n {\n resetKey: resetKey.value,\n onError: props.onCatch,\n },\n {\n default: () => props.children,\n fallback: ({ error, reset }: ErrorComponentProps) => {\n if (props.errorComponent) {\n return Vue.h(props.errorComponent, { error, reset })\n }\n return Vue.h(ErrorComponent, { error, reset })\n },\n },\n )\n }\n },\n})\n\nexport function CatchBoundary(props: CatchBoundaryProps) {\n return Vue.h(CatchBoundaryWrapper, props as any)\n}\n\nexport const ErrorComponent = Vue.defineComponent({\n name: 'ErrorComponent',\n props: {\n error: Object,\n reset: Function,\n },\n setup(props) {\n const show = Vue.ref(process.env.NODE_ENV !== 'production')\n\n const toggleShow = () => {\n show.value = !show.value\n }\n\n return () =>\n Vue.h('div', { style: { padding: '.5rem', maxWidth: '100%' } }, [\n Vue.h(\n 'div',\n { style: { display: 'flex', alignItems: 'center', gap: '.5rem' } },\n [\n Vue.h(\n 'strong',\n { style: { fontSize: '1rem' } },\n 'Something went wrong!',\n ),\n Vue.h(\n 'button',\n {\n style: {\n appearance: 'none',\n fontSize: '.6em',\n border: '1px solid currentColor',\n padding: '.1rem .2rem',\n fontWeight: 'bold',\n borderRadius: '.25rem',\n },\n onClick: toggleShow,\n },\n show.value ? 'Hide Error' : 'Show Error',\n ),\n ],\n ),\n Vue.h('div', { style: { height: '.25rem' } }),\n show.value\n ? Vue.h('div', {}, [\n Vue.h(\n 'pre',\n {\n style: {\n fontSize: '.7em',\n border: '1px solid red',\n borderRadius: '.25rem',\n padding: '.3rem',\n color: 'red',\n overflow: 'auto',\n },\n },\n [\n props.error?.message\n ? Vue.h('code', {}, props.error.message)\n : null,\n ],\n ),\n ])\n : null,\n ])\n },\n})\n"],"names":["VueErrorBoundary","Vue","defineComponent","name","props","onError","Function","resetKey","String","Number","emits","setup","slots","error","ref","resetFn","reset","value","watch","newKey","oldKey","onErrorCaptured","err","Promise","then","fallback","fallbackContent","Array","isArray","length","defaultContent","default","CatchBoundaryWrapper","inheritAttrs","computed","getResetKey","h","onCatch","children","errorComponent","ErrorComponent","CatchBoundary","Object","show","process","env","NODE_ENV","toggleShow","style","padding","maxWidth","display","alignItems","gap","fontSize","appearance","border","fontWeight","borderRadius","onClick","height","color","overflow","message"],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import * as Vue from "vue";
2
+ const ClientOnly = Vue.defineComponent({
3
+ name: "ClientOnly",
4
+ props: {
5
+ fallback: {
6
+ type: Object,
7
+ default: null
8
+ }
9
+ },
10
+ setup(props, {
11
+ slots
12
+ }) {
13
+ const hydrated = useHydrated();
14
+ return () => {
15
+ if (hydrated.value) {
16
+ return slots.default?.();
17
+ }
18
+ return props.fallback ?? null;
19
+ };
20
+ }
21
+ });
22
+ function useHydrated() {
23
+ const hydrated = Vue.ref(false);
24
+ Vue.onMounted(() => {
25
+ hydrated.value = true;
26
+ });
27
+ return hydrated;
28
+ }
29
+ export {
30
+ ClientOnly,
31
+ useHydrated
32
+ };
33
+ //# sourceMappingURL=ClientOnly.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientOnly.js","sources":["../../src/ClientOnly.tsx"],"sourcesContent":["import * as Vue from 'vue'\n\nexport interface ClientOnlyProps {\n /**\n * The children to render when the JS is loaded.\n */\n children?: Vue.VNode\n /**\n * The fallback component to render if the JS is not yet loaded.\n */\n fallback?: Vue.VNode\n}\n\n/**\n * Render the children only after the JS has loaded client-side. Use an optional\n * fallback component if the JS is not yet loaded.\n *\n * @example\n * Render a Chart component if JS loads, renders a simple FakeChart\n * component server-side or if there is no JS. The FakeChart can have only the\n * UI without the behavior or be a loading spinner or skeleton.\n *\n * ```tsx\n * return (\n * <ClientOnly fallback={<FakeChart />}>\n * <Chart />\n * </ClientOnly>\n * )\n * ```\n */\nexport const ClientOnly = Vue.defineComponent({\n name: 'ClientOnly',\n props: {\n fallback: {\n type: Object as Vue.PropType<Vue.VNode>,\n default: null,\n },\n },\n setup(props, { slots }) {\n const hydrated = useHydrated()\n return () => {\n if (hydrated.value) {\n return slots.default?.()\n }\n return props.fallback ?? null\n }\n },\n})\n\n/**\n * Return a boolean indicating if the JS has been hydrated already.\n * When doing Server-Side Rendering, the result will always be false.\n * When doing Client-Side Rendering, the result will always be false on the\n * first render and true from then on. Even if a new component renders it will\n * always start with true.\n *\n * @example\n * ```tsx\n * // Disable a button that needs JS to work.\n * const hydrated = useHydrated()\n * return (\n * <button type=\"button\" disabled={!hydrated.value} onClick={doSomethingCustom}>\n * Click me\n * </button>\n * )\n * ```\n * @returns True if the JS has been hydrated already, false otherwise.\n */\nexport function useHydrated(): Vue.Ref<boolean> {\n const hydrated = Vue.ref(false)\n Vue.onMounted(() => {\n hydrated.value = true\n })\n return hydrated\n}\n"],"names":["ClientOnly","Vue","defineComponent","name","props","fallback","type","Object","default","setup","slots","hydrated","useHydrated","value","ref","onMounted"],"mappings":";MA8BaA,aAAaC,IAAIC,gBAAgB;AAAA,EAC5CC,MAAM;AAAA,EACNC,OAAO;AAAA,IACLC,UAAU;AAAA,MACRC,MAAMC;AAAAA,MACNC,SAAS;AAAA,IACX;AAAA;EAEFC,MAAML,OAAO;AAAA,IAAEM;AAAAA,EAAM,GAAG;AACtB,UAAMC,WAAWC,YAAW;AAC5B,WAAO,MAAM;AACX,UAAID,SAASE,OAAO;AAClB,eAAOH,MAAMF,UAAO;AAAA,MACtB;AACA,aAAOJ,MAAMC,YAAY;AAAA,IAC3B;AAAA,EACF;AACF,CAAC;AAqBM,SAASO,cAAgC;AAC9C,QAAMD,WAAWV,IAAIa,IAAI,KAAK;AAC9Bb,MAAIc,UAAU,MAAM;AAClBJ,aAASE,QAAQ;AAAA,EACnB,CAAC;AACD,SAAOF;AACT;"}
package/dist/esm/Match.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import * as Vue from "vue";
2
2
  import invariant from "tiny-invariant";
3
3
  import warning from "tiny-warning";
4
- import { isNotFound, rootRouteId, isRedirect, createControlledPromise, getLocationChangeInfo } from "@tanstack/router-core";
4
+ import { rootRouteId, isNotFound, isRedirect, createControlledPromise, getLocationChangeInfo } from "@tanstack/router-core";
5
5
  import { CatchBoundary, ErrorComponent } from "./CatchBoundary.js";
6
+ import { ClientOnly } from "./ClientOnly.js";
6
7
  import { useRouterState } from "./useRouterState.js";
7
8
  import { useRouter } from "./useRouter.js";
8
9
  import { CatchNotFound } from "./not-found.js";
@@ -40,19 +41,27 @@ const Match = Vue.defineComponent({
40
41
  // Return the actual matchId (may differ from props.matchId)
41
42
  routeId,
42
43
  parentRouteId,
43
- loadedAt: s.loadedAt
44
+ loadedAt: s.loadedAt,
45
+ ssr: match.ssr,
46
+ _displayPending: match._displayPending
44
47
  };
45
48
  }
46
49
  });
47
50
  invariant(matchData.value, `Could not find routeId for matchId "${props.matchId}". Please file an issue!`);
48
51
  const route = Vue.computed(() => matchData.value ? router.routesById[matchData.value.routeId] : null);
49
52
  const PendingComponent = Vue.computed(() => route.value?.options?.pendingComponent ?? router?.options?.defaultPendingComponent);
53
+ const pendingElement = Vue.computed(() => PendingComponent.value ? Vue.h(PendingComponent.value) : void 0);
50
54
  const routeErrorComponent = Vue.computed(() => route.value?.options?.errorComponent ?? router?.options?.defaultErrorComponent);
51
55
  const routeOnCatch = Vue.computed(() => route.value?.options?.onCatch ?? router?.options?.defaultOnCatch);
52
56
  const routeNotFoundComponent = Vue.computed(() => route.value?.isRoot ? (
53
57
  // If it's the root route, use the globalNotFound option, with fallback to the notFoundRoute's component
54
58
  route.value?.options?.notFoundComponent ?? router?.options?.notFoundRoute?.options?.component
55
59
  ) : route.value?.options?.notFoundComponent);
60
+ const hasShellComponent = Vue.computed(() => {
61
+ if (!route.value?.isRoot) return false;
62
+ return !!route.value.options.shellComponent;
63
+ });
64
+ const ShellComponent = Vue.computed(() => hasShellComponent.value ? route.value.options.shellComponent : null);
56
65
  const matchIdRef = Vue.ref(matchData.value?.matchId ?? props.matchId);
57
66
  Vue.watch([() => props.matchId, () => matchData.value?.matchId], ([propsMatchId, dataMatchId]) => {
58
67
  matchIdRef.value = dataMatchId ?? propsMatchId;
@@ -62,43 +71,52 @@ const Match = Vue.defineComponent({
62
71
  Vue.provide(matchContext, matchIdRef);
63
72
  return () => {
64
73
  const actualMatchId = matchData.value?.matchId ?? props.matchId;
65
- let content = Vue.h(MatchInner, {
66
- matchId: actualMatchId
67
- });
68
- if (routeNotFoundComponent.value) {
69
- content = Vue.h(CatchNotFound, {
70
- fallback: (error) => {
71
- if (!routeNotFoundComponent.value || error.routeId && error.routeId !== matchData.value?.routeId || !error.routeId && route.value && !route.value.isRoot) throw error;
72
- return Vue.h(routeNotFoundComponent.value, error);
73
- },
74
- children: content
75
- });
76
- }
77
- if (routeErrorComponent.value) {
78
- content = CatchBoundary({
79
- getResetKey: () => matchData.value?.loadedAt ?? 0,
80
- errorComponent: routeErrorComponent.value || ErrorComponent,
81
- onCatch: (error) => {
82
- if (isNotFound(error)) throw error;
83
- warning(false, `Error in route match: ${actualMatchId}`);
84
- routeOnCatch.value?.(error);
85
- },
86
- children: content
74
+ const resolvedNoSsr = matchData.value?.ssr === false || matchData.value?.ssr === "data-only";
75
+ const shouldClientOnly = resolvedNoSsr || !!matchData.value?._displayPending;
76
+ const renderMatchContent = () => {
77
+ const matchInner = Vue.h(MatchInner, {
78
+ matchId: actualMatchId
87
79
  });
88
- }
89
- const needsSuspense = route.value && (route.value?.options?.wrapInSuspense ?? PendingComponent.value ?? false);
90
- if (needsSuspense) {
91
- content = Vue.h(Vue.Suspense, {
92
- fallback: PendingComponent.value ? Vue.h(PendingComponent.value) : null
80
+ let content = shouldClientOnly ? Vue.h(ClientOnly, {
81
+ fallback: pendingElement.value
93
82
  }, {
94
- default: () => content
95
- });
96
- }
97
- const withScrollRestoration = [content, matchData.value?.parentRouteId === rootRouteId && router.options.scrollRestoration ? Vue.h(Vue.Fragment, null, [Vue.h(OnRendered), Vue.h(ScrollRestoration)]) : null].filter(Boolean);
98
- if (withScrollRestoration.length === 1) {
99
- return withScrollRestoration[0];
83
+ default: () => matchInner
84
+ }) : matchInner;
85
+ if (routeNotFoundComponent.value) {
86
+ content = Vue.h(CatchNotFound, {
87
+ fallback: (error) => {
88
+ if (!routeNotFoundComponent.value || error.routeId && error.routeId !== matchData.value?.routeId || !error.routeId && route.value && !route.value.isRoot) throw error;
89
+ return Vue.h(routeNotFoundComponent.value, error);
90
+ },
91
+ children: content
92
+ });
93
+ }
94
+ if (routeErrorComponent.value) {
95
+ content = CatchBoundary({
96
+ getResetKey: () => matchData.value?.loadedAt ?? 0,
97
+ errorComponent: routeErrorComponent.value || ErrorComponent,
98
+ onCatch: (error) => {
99
+ if (isNotFound(error)) throw error;
100
+ warning(false, `Error in route match: ${actualMatchId}`);
101
+ routeOnCatch.value?.(error);
102
+ },
103
+ children: content
104
+ });
105
+ }
106
+ const withScrollRestoration = [content, matchData.value?.parentRouteId === rootRouteId && router.options.scrollRestoration ? Vue.h(Vue.Fragment, null, [Vue.h(OnRendered), Vue.h(ScrollRestoration)]) : null].filter(Boolean);
107
+ if (withScrollRestoration.length === 1) {
108
+ return withScrollRestoration[0];
109
+ }
110
+ return Vue.h(Vue.Fragment, null, withScrollRestoration);
111
+ };
112
+ if (!hasShellComponent.value) {
113
+ return renderMatchContent();
100
114
  }
101
- return Vue.h(Vue.Fragment, null, withScrollRestoration);
115
+ return Vue.h(ShellComponent.value, null, {
116
+ // Important: return a fresh VNode on each slot invocation so that shell
117
+ // components can re-render without reusing a cached VNode instance.
118
+ default: () => renderMatchContent()
119
+ });
102
120
  };
103
121
  }
104
122
  });
@@ -164,7 +182,10 @@ const MatchInner = Vue.defineComponent({
164
182
  match: {
165
183
  id: match2.id,
166
184
  status: match2.status,
167
- error: match2.error
185
+ error: match2.error,
186
+ ssr: match2.ssr,
187
+ _forcePending: match2._forcePending,
188
+ _displayPending: match2._displayPending
168
189
  },
169
190
  remountKey: remountKey2
170
191
  };
@@ -177,8 +198,14 @@ const MatchInner = Vue.defineComponent({
177
198
  const match = Vue.computed(() => combinedState.value?.match);
178
199
  const remountKey = Vue.computed(() => combinedState.value?.remountKey);
179
200
  return () => {
180
- if (!combinedState.value || !match.value || !route.value) {
181
- return null;
201
+ if (!combinedState.value || !match.value || !route.value) return null;
202
+ if (match.value._displayPending) {
203
+ const PendingComponent = route.value.options.pendingComponent ?? router.options.defaultPendingComponent;
204
+ return PendingComponent ? Vue.h(PendingComponent) : null;
205
+ }
206
+ if (match.value._forcePending) {
207
+ const PendingComponent = route.value.options.pendingComponent ?? router.options.defaultPendingComponent;
208
+ return PendingComponent ? Vue.h(PendingComponent) : null;
182
209
  }
183
210
  if (match.value.status === "notFound") {
184
211
  invariant(isNotFound(match.value.error), "Expected a notFound error");
@@ -1 +1 @@
1
- {"version":3,"file":"Match.js","sources":["../../src/Match.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport invariant from 'tiny-invariant'\nimport warning from 'tiny-warning'\nimport {\n createControlledPromise,\n getLocationChangeInfo,\n isNotFound,\n isRedirect,\n rootRouteId,\n} from '@tanstack/router-core'\nimport { CatchBoundary, ErrorComponent } from './CatchBoundary'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport { CatchNotFound } from './not-found'\nimport { matchContext } from './matchContext'\nimport { renderRouteNotFound } from './renderRouteNotFound'\nimport { ScrollRestoration } from './scroll-restoration'\nimport type { VNode } from 'vue'\nimport type { AnyRoute } from '@tanstack/router-core'\n\nexport const Match = Vue.defineComponent({\n name: 'Match',\n props: {\n matchId: {\n type: String,\n required: true,\n },\n },\n setup(props) {\n const router = useRouter()\n\n // Track the last known routeId to handle stale props during same-route transitions\n let lastKnownRouteId: string | null = null\n\n // Combined selector that returns all needed data including the actual matchId\n // This handles stale props.matchId during same-route transitions\n const matchData = useRouterState({\n select: (s) => {\n // First try to find match by props.matchId\n let match = s.matches.find((d) => d.id === props.matchId)\n let matchIndex = match\n ? s.matches.findIndex((d) => d.id === props.matchId)\n : -1\n\n // If match found, update lastKnownRouteId\n if (match) {\n lastKnownRouteId = match.routeId as string\n } else if (lastKnownRouteId) {\n // Match not found - props.matchId might be stale during a same-route transition\n // Try to find the NEW match by routeId\n match = s.matches.find((d) => d.routeId === lastKnownRouteId)\n matchIndex = match\n ? s.matches.findIndex((d) => d.routeId === lastKnownRouteId)\n : -1\n }\n\n if (!match) {\n return null\n }\n\n const routeId = match.routeId as string\n const parentRouteId =\n matchIndex > 0 ? (s.matches[matchIndex - 1]?.routeId as string) : null\n\n return {\n matchId: match.id, // Return the actual matchId (may differ from props.matchId)\n routeId,\n parentRouteId,\n loadedAt: s.loadedAt,\n }\n },\n })\n\n invariant(\n matchData.value,\n `Could not find routeId for matchId \"${props.matchId}\". Please file an issue!`,\n )\n\n const route = Vue.computed(() =>\n matchData.value ? router.routesById[matchData.value.routeId] : null,\n )\n\n const PendingComponent = Vue.computed(\n () =>\n route.value?.options?.pendingComponent ??\n router?.options?.defaultPendingComponent,\n )\n\n const routeErrorComponent = Vue.computed(\n () =>\n route.value?.options?.errorComponent ??\n router?.options?.defaultErrorComponent,\n )\n\n const routeOnCatch = Vue.computed(\n () => route.value?.options?.onCatch ?? router?.options?.defaultOnCatch,\n )\n\n const routeNotFoundComponent = Vue.computed(() =>\n route.value?.isRoot\n ? // If it's the root route, use the globalNotFound option, with fallback to the notFoundRoute's component\n (route.value?.options?.notFoundComponent ??\n router?.options?.notFoundRoute?.options?.component)\n : route.value?.options?.notFoundComponent,\n )\n\n // Create a ref for the current matchId that we provide to child components\n // This ref is updated to the ACTUAL matchId found (which may differ from props during transitions)\n const matchIdRef = Vue.ref(matchData.value?.matchId ?? props.matchId)\n\n // Watch both props.matchId and matchData to keep matchIdRef in sync\n // This ensures Outlet gets the correct matchId even during transitions\n Vue.watch(\n [() => props.matchId, () => matchData.value?.matchId],\n ([propsMatchId, dataMatchId]) => {\n // Prefer the matchId from matchData (which handles fallback)\n // Fall back to props.matchId if matchData is null\n matchIdRef.value = dataMatchId ?? propsMatchId\n },\n { immediate: true },\n )\n\n // Provide the matchId to child components\n Vue.provide(matchContext, matchIdRef)\n\n return (): VNode => {\n // Use the actual matchId from matchData, not props (which may be stale)\n const actualMatchId = matchData.value?.matchId ?? props.matchId\n\n // Determine which components to render\n let content: VNode = Vue.h(MatchInner, { matchId: actualMatchId })\n\n // Wrap in NotFound boundary if needed\n if (routeNotFoundComponent.value) {\n content = Vue.h(CatchNotFound, {\n fallback: (error: any) => {\n // If the current not found handler doesn't exist or it has a\n // route ID which doesn't match the current route, rethrow the error\n if (\n !routeNotFoundComponent.value ||\n (error.routeId && error.routeId !== matchData.value?.routeId) ||\n (!error.routeId && route.value && !route.value.isRoot)\n )\n throw error\n\n return Vue.h(routeNotFoundComponent.value, error)\n },\n children: content,\n })\n }\n\n // Wrap in error boundary if needed\n if (routeErrorComponent.value) {\n content = CatchBoundary({\n getResetKey: () => matchData.value?.loadedAt ?? 0,\n errorComponent: routeErrorComponent.value || ErrorComponent,\n onCatch: (error: Error) => {\n // Forward not found errors (we don't want to show the error component for these)\n if (isNotFound(error)) throw error\n warning(false, `Error in route match: ${actualMatchId}`)\n routeOnCatch.value?.(error)\n },\n children: content,\n })\n }\n\n // Wrap in suspense if needed\n // Root routes should also wrap in Suspense if they have a pendingComponent\n const needsSuspense =\n route.value &&\n (route.value?.options?.wrapInSuspense ??\n PendingComponent.value ??\n false)\n\n if (needsSuspense) {\n content = Vue.h(\n Vue.Suspense,\n {\n fallback: PendingComponent.value\n ? Vue.h(PendingComponent.value)\n : null,\n },\n {\n default: () => content,\n },\n )\n }\n\n // Add scroll restoration if needed\n const withScrollRestoration: Array<VNode> = [\n content,\n matchData.value?.parentRouteId === rootRouteId &&\n router.options.scrollRestoration\n ? Vue.h(Vue.Fragment, null, [\n Vue.h(OnRendered),\n Vue.h(ScrollRestoration),\n ])\n : null,\n ].filter(Boolean) as Array<VNode>\n\n // Return single child directly to avoid Fragment wrapper that causes hydration mismatch\n if (withScrollRestoration.length === 1) {\n return withScrollRestoration[0]!\n }\n return Vue.h(Vue.Fragment, null, withScrollRestoration)\n }\n },\n})\n\n// On Rendered can't happen above the root layout because it actually\n// renders a dummy dom element to track the rendered state of the app.\n// We render a script tag with a key that changes based on the current\n// location state.key. Also, because it's below the root layout, it\n// allows us to fire onRendered events even after a hydration mismatch\n// error that occurred above the root layout (like bad head/link tags,\n// which is common).\nconst OnRendered = Vue.defineComponent({\n name: 'OnRendered',\n setup() {\n const router = useRouter()\n\n const location = useRouterState({\n select: (s) => {\n return s.resolvedLocation?.state.key\n },\n })\n\n Vue.watchEffect(() => {\n if (location.value) {\n router.emit({\n type: 'onRendered',\n ...getLocationChangeInfo(router.state),\n })\n }\n })\n\n return () => null\n },\n})\n\nexport const MatchInner = Vue.defineComponent({\n name: 'MatchInner',\n props: {\n matchId: {\n type: String,\n required: true,\n },\n },\n setup(props) {\n const router = useRouter()\n\n // Track the last known routeId to handle stale props during same-route transitions\n // This is stored outside the selector so it persists across selector calls\n let lastKnownRouteId: string | null = null\n\n // Combined selector for match state AND remount key\n // This ensures both are computed in the same selector call with consistent data\n const combinedState = useRouterState({\n select: (s) => {\n // First try to find match by props.matchId\n let match = s.matches.find((d) => d.id === props.matchId)\n\n // If match found, update lastKnownRouteId\n if (match) {\n lastKnownRouteId = match.routeId as string\n } else if (lastKnownRouteId) {\n // Match not found - props.matchId might be stale during a same-route transition\n // (matchId changed due to loaderDepsHash but props haven't updated yet)\n // Try to find the NEW match by routeId and use that instead\n const sameRouteMatch = s.matches.find(\n (d) => d.routeId === lastKnownRouteId,\n )\n if (sameRouteMatch) {\n match = sameRouteMatch\n }\n }\n\n if (!match) {\n // Route no longer exists - truly navigating away\n return null\n }\n\n const routeId = match.routeId as string\n\n // Compute remount key\n const remountFn =\n (router.routesById[routeId] as AnyRoute).options.remountDeps ??\n router.options.defaultRemountDeps\n\n let remountKey: string | undefined\n if (remountFn) {\n const remountDeps = remountFn({\n routeId,\n loaderDeps: match.loaderDeps,\n params: match._strictParams,\n search: match._strictSearch,\n })\n remountKey = remountDeps ? JSON.stringify(remountDeps) : undefined\n }\n\n return {\n routeId,\n match: {\n id: match.id,\n status: match.status,\n error: match.error,\n },\n remountKey,\n }\n },\n })\n\n const route = Vue.computed(() => {\n if (!combinedState.value) return null\n return router.routesById[combinedState.value.routeId]!\n })\n\n const match = Vue.computed(() => combinedState.value?.match)\n const remountKey = Vue.computed(() => combinedState.value?.remountKey)\n\n return (): VNode | null => {\n // If match doesn't exist, return null (component is being unmounted or not ready)\n if (!combinedState.value || !match.value || !route.value) {\n return null\n }\n\n // Handle different match statuses\n if (match.value.status === 'notFound') {\n invariant(isNotFound(match.value.error), 'Expected a notFound error')\n return renderRouteNotFound(router, route.value, match.value.error)\n }\n\n if (match.value.status === 'redirected') {\n invariant(isRedirect(match.value.error), 'Expected a redirect error')\n throw router.getMatch(match.value.id)?._nonReactive.loadPromise\n }\n\n if (match.value.status === 'error') {\n // Check if this route or any parent has an error component\n const RouteErrorComponent =\n route.value.options.errorComponent ??\n router.options.defaultErrorComponent\n\n // If this route has an error component, render it directly\n // This is more reliable than relying on Vue's error boundary\n if (RouteErrorComponent) {\n return Vue.h(RouteErrorComponent, {\n error: match.value.error,\n reset: () => {\n router.invalidate()\n },\n info: {\n componentStack: '',\n },\n })\n }\n\n // If there's no error component for this route, throw the error\n // so it can bubble up to the nearest parent with an error component\n throw match.value.error\n }\n\n if (match.value.status === 'pending') {\n const pendingMinMs =\n route.value.options.pendingMinMs ?? router.options.defaultPendingMinMs\n\n const routerMatch = router.getMatch(match.value.id)\n if (\n pendingMinMs &&\n routerMatch &&\n !routerMatch._nonReactive.minPendingPromise\n ) {\n // Create a promise that will resolve after the minPendingMs\n if (!router.isServer) {\n const minPendingPromise = createControlledPromise<void>()\n\n routerMatch._nonReactive.minPendingPromise = minPendingPromise\n\n setTimeout(() => {\n minPendingPromise.resolve()\n // We've handled the minPendingPromise, so we can delete it\n routerMatch._nonReactive.minPendingPromise = undefined\n }, pendingMinMs)\n }\n }\n\n // In Vue, we render the pending component directly instead of throwing a promise\n // because Vue's Suspense doesn't catch thrown promises like React does\n const PendingComponent =\n route.value.options.pendingComponent ??\n router.options.defaultPendingComponent\n\n if (PendingComponent) {\n return Vue.h(PendingComponent)\n }\n\n // If no pending component, return null while loading\n return null\n }\n\n // Success status - render the component with remount key\n const Comp =\n route.value.options.component ?? router.options.defaultComponent\n const key = remountKey.value\n\n if (Comp) {\n // Pass key as a prop - Vue.h properly handles 'key' as a special prop\n return Vue.h(Comp, key !== undefined ? { key } : undefined)\n }\n\n return Vue.h(Outlet, key !== undefined ? { key } : undefined)\n }\n },\n})\n\nexport const Outlet = Vue.defineComponent({\n name: 'Outlet',\n setup() {\n const router = useRouter()\n const matchId = Vue.inject(matchContext)\n const safeMatchId = Vue.computed(() => matchId?.value || '')\n\n const routeId = useRouterState({\n select: (s) =>\n s.matches.find((d) => d.id === safeMatchId.value)?.routeId as string,\n })\n\n const route = Vue.computed(() => router.routesById[routeId.value]!)\n\n const parentGlobalNotFound = useRouterState({\n select: (s) => {\n const matches = s.matches\n const parentMatch = matches.find((d) => d.id === safeMatchId.value)\n\n // During navigation transitions, parent match can be temporarily removed\n // Return false to avoid errors - the component will handle this gracefully\n if (!parentMatch) {\n return false\n }\n\n return parentMatch.globalNotFound\n },\n })\n\n const childMatchData = useRouterState({\n select: (s) => {\n const matches = s.matches\n const index = matches.findIndex((d) => d.id === safeMatchId.value)\n const child = matches[index + 1]\n if (!child) return null\n return {\n id: child.id,\n // Key based on routeId + params only (not loaderDeps)\n // This ensures component recreates when params change,\n // but NOT when only loaderDeps change\n paramsKey: child.routeId + JSON.stringify(child._strictParams),\n }\n },\n })\n\n return (): VNode | null => {\n if (parentGlobalNotFound.value) {\n return renderRouteNotFound(router, route.value, undefined)\n }\n\n if (!childMatchData.value) {\n return null\n }\n\n const nextMatch = Vue.h(Match, {\n matchId: childMatchData.value.id,\n key: childMatchData.value.paramsKey,\n })\n\n if (safeMatchId.value === rootRouteId) {\n return Vue.h(\n Vue.Suspense,\n {\n fallback: router.options.defaultPendingComponent\n ? Vue.h(router.options.defaultPendingComponent)\n : null,\n },\n {\n default: () => nextMatch,\n },\n )\n }\n\n return nextMatch\n }\n },\n})\n"],"names":["Match","Vue","defineComponent","name","props","matchId","type","String","required","setup","router","useRouter","lastKnownRouteId","matchData","useRouterState","select","s","match","matches","find","d","id","matchIndex","findIndex","routeId","parentRouteId","loadedAt","invariant","value","route","computed","routesById","PendingComponent","options","pendingComponent","defaultPendingComponent","routeErrorComponent","errorComponent","defaultErrorComponent","routeOnCatch","onCatch","defaultOnCatch","routeNotFoundComponent","isRoot","notFoundComponent","notFoundRoute","component","matchIdRef","ref","watch","propsMatchId","dataMatchId","immediate","provide","matchContext","actualMatchId","content","h","MatchInner","CatchNotFound","fallback","error","children","CatchBoundary","getResetKey","ErrorComponent","isNotFound","warning","needsSuspense","wrapInSuspense","Suspense","default","withScrollRestoration","rootRouteId","scrollRestoration","Fragment","OnRendered","ScrollRestoration","filter","Boolean","length","location","resolvedLocation","state","key","watchEffect","emit","getLocationChangeInfo","combinedState","sameRouteMatch","remountFn","remountDeps","defaultRemountDeps","remountKey","loaderDeps","params","_strictParams","search","_strictSearch","JSON","stringify","undefined","status","renderRouteNotFound","isRedirect","getMatch","_nonReactive","loadPromise","RouteErrorComponent","reset","invalidate","info","componentStack","pendingMinMs","defaultPendingMinMs","routerMatch","minPendingPromise","isServer","createControlledPromise","setTimeout","resolve","Comp","defaultComponent","Outlet","inject","safeMatchId","parentGlobalNotFound","parentMatch","globalNotFound","childMatchData","index","child","paramsKey","nextMatch"],"mappings":"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"}
1
+ {"version":3,"file":"Match.js","sources":["../../src/Match.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport invariant from 'tiny-invariant'\nimport warning from 'tiny-warning'\nimport {\n createControlledPromise,\n getLocationChangeInfo,\n isNotFound,\n isRedirect,\n rootRouteId,\n} from '@tanstack/router-core'\nimport { CatchBoundary, ErrorComponent } from './CatchBoundary'\nimport { ClientOnly } from './ClientOnly'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport { CatchNotFound } from './not-found'\nimport { matchContext } from './matchContext'\nimport { renderRouteNotFound } from './renderRouteNotFound'\nimport { ScrollRestoration } from './scroll-restoration'\nimport type { VNode } from 'vue'\nimport type { AnyRoute, RootRouteOptions } from '@tanstack/router-core'\n\nexport const Match = Vue.defineComponent({\n name: 'Match',\n props: {\n matchId: {\n type: String,\n required: true,\n },\n },\n setup(props) {\n const router = useRouter()\n\n // Track the last known routeId to handle stale props during same-route transitions\n let lastKnownRouteId: string | null = null\n\n // Combined selector that returns all needed data including the actual matchId\n // This handles stale props.matchId during same-route transitions\n const matchData = useRouterState({\n select: (s) => {\n // First try to find match by props.matchId\n let match = s.matches.find((d) => d.id === props.matchId)\n let matchIndex = match\n ? s.matches.findIndex((d) => d.id === props.matchId)\n : -1\n\n // If match found, update lastKnownRouteId\n if (match) {\n lastKnownRouteId = match.routeId as string\n } else if (lastKnownRouteId) {\n // Match not found - props.matchId might be stale during a same-route transition\n // Try to find the NEW match by routeId\n match = s.matches.find((d) => d.routeId === lastKnownRouteId)\n matchIndex = match\n ? s.matches.findIndex((d) => d.routeId === lastKnownRouteId)\n : -1\n }\n\n if (!match) {\n return null\n }\n\n const routeId = match.routeId as string\n const parentRouteId =\n matchIndex > 0 ? (s.matches[matchIndex - 1]?.routeId as string) : null\n\n return {\n matchId: match.id, // Return the actual matchId (may differ from props.matchId)\n routeId,\n parentRouteId,\n loadedAt: s.loadedAt,\n ssr: match.ssr,\n _displayPending: match._displayPending,\n }\n },\n })\n\n invariant(\n matchData.value,\n `Could not find routeId for matchId \"${props.matchId}\". Please file an issue!`,\n )\n\n const route = Vue.computed(() =>\n matchData.value ? router.routesById[matchData.value.routeId] : null,\n )\n\n const PendingComponent = Vue.computed(\n () =>\n route.value?.options?.pendingComponent ??\n router?.options?.defaultPendingComponent,\n )\n\n const pendingElement = Vue.computed(() =>\n PendingComponent.value ? Vue.h(PendingComponent.value) : undefined,\n )\n\n const routeErrorComponent = Vue.computed(\n () =>\n route.value?.options?.errorComponent ??\n router?.options?.defaultErrorComponent,\n )\n\n const routeOnCatch = Vue.computed(\n () => route.value?.options?.onCatch ?? router?.options?.defaultOnCatch,\n )\n\n const routeNotFoundComponent = Vue.computed(() =>\n route.value?.isRoot\n ? // If it's the root route, use the globalNotFound option, with fallback to the notFoundRoute's component\n (route.value?.options?.notFoundComponent ??\n router?.options?.notFoundRoute?.options?.component)\n : route.value?.options?.notFoundComponent,\n )\n\n const hasShellComponent = Vue.computed(() => {\n if (!route.value?.isRoot) return false\n return !!(route.value.options as RootRouteOptions).shellComponent\n })\n\n const ShellComponent = Vue.computed(() =>\n hasShellComponent.value\n ? ((route.value!.options as RootRouteOptions).shellComponent as any)\n : null,\n )\n\n // Create a ref for the current matchId that we provide to child components\n // This ref is updated to the ACTUAL matchId found (which may differ from props during transitions)\n const matchIdRef = Vue.ref(matchData.value?.matchId ?? props.matchId)\n\n // Watch both props.matchId and matchData to keep matchIdRef in sync\n // This ensures Outlet gets the correct matchId even during transitions\n Vue.watch(\n [() => props.matchId, () => matchData.value?.matchId],\n ([propsMatchId, dataMatchId]) => {\n // Prefer the matchId from matchData (which handles fallback)\n // Fall back to props.matchId if matchData is null\n matchIdRef.value = dataMatchId ?? propsMatchId\n },\n { immediate: true },\n )\n\n // Provide the matchId to child components\n Vue.provide(matchContext, matchIdRef)\n\n return (): VNode => {\n // Use the actual matchId from matchData, not props (which may be stale)\n const actualMatchId = matchData.value?.matchId ?? props.matchId\n\n const resolvedNoSsr =\n matchData.value?.ssr === false || matchData.value?.ssr === 'data-only'\n const shouldClientOnly =\n resolvedNoSsr || !!matchData.value?._displayPending\n\n const renderMatchContent = (): VNode => {\n const matchInner = Vue.h(MatchInner, { matchId: actualMatchId })\n\n let content: VNode = shouldClientOnly\n ? Vue.h(\n ClientOnly,\n {\n fallback: pendingElement.value,\n },\n {\n default: () => matchInner,\n },\n )\n : matchInner\n\n // Wrap in NotFound boundary if needed\n if (routeNotFoundComponent.value) {\n content = Vue.h(CatchNotFound, {\n fallback: (error: any) => {\n // If the current not found handler doesn't exist or it has a\n // route ID which doesn't match the current route, rethrow the error\n if (\n !routeNotFoundComponent.value ||\n (error.routeId && error.routeId !== matchData.value?.routeId) ||\n (!error.routeId && route.value && !route.value.isRoot)\n )\n throw error\n\n return Vue.h(routeNotFoundComponent.value, error)\n },\n children: content,\n })\n }\n\n // Wrap in error boundary if needed\n if (routeErrorComponent.value) {\n content = CatchBoundary({\n getResetKey: () => matchData.value?.loadedAt ?? 0,\n errorComponent: routeErrorComponent.value || ErrorComponent,\n onCatch: (error: Error) => {\n // Forward not found errors (we don't want to show the error component for these)\n if (isNotFound(error)) throw error\n warning(false, `Error in route match: ${actualMatchId}`)\n routeOnCatch.value?.(error)\n },\n children: content,\n })\n }\n\n // Add scroll restoration if needed\n const withScrollRestoration: Array<VNode> = [\n content,\n matchData.value?.parentRouteId === rootRouteId &&\n router.options.scrollRestoration\n ? Vue.h(Vue.Fragment, null, [\n Vue.h(OnRendered),\n Vue.h(ScrollRestoration),\n ])\n : null,\n ].filter(Boolean) as Array<VNode>\n\n // Return single child directly to avoid Fragment wrapper that causes hydration mismatch\n if (withScrollRestoration.length === 1) {\n return withScrollRestoration[0]!\n }\n\n return Vue.h(Vue.Fragment, null, withScrollRestoration)\n }\n\n if (!hasShellComponent.value) {\n return renderMatchContent()\n }\n\n return Vue.h(ShellComponent.value, null, {\n // Important: return a fresh VNode on each slot invocation so that shell\n // components can re-render without reusing a cached VNode instance.\n default: () => renderMatchContent(),\n })\n }\n },\n})\n\n// On Rendered can't happen above the root layout because it actually\n// renders a dummy dom element to track the rendered state of the app.\n// We render a script tag with a key that changes based on the current\n// location state.key. Also, because it's below the root layout, it\n// allows us to fire onRendered events even after a hydration mismatch\n// error that occurred above the root layout (like bad head/link tags,\n// which is common).\nconst OnRendered = Vue.defineComponent({\n name: 'OnRendered',\n setup() {\n const router = useRouter()\n\n const location = useRouterState({\n select: (s) => {\n return s.resolvedLocation?.state.key\n },\n })\n\n Vue.watchEffect(() => {\n if (location.value) {\n router.emit({\n type: 'onRendered',\n ...getLocationChangeInfo(router.state),\n })\n }\n })\n\n return () => null\n },\n})\n\nexport const MatchInner = Vue.defineComponent({\n name: 'MatchInner',\n props: {\n matchId: {\n type: String,\n required: true,\n },\n },\n setup(props) {\n const router = useRouter()\n\n // Track the last known routeId to handle stale props during same-route transitions\n // This is stored outside the selector so it persists across selector calls\n let lastKnownRouteId: string | null = null\n\n // Combined selector for match state AND remount key\n // This ensures both are computed in the same selector call with consistent data\n const combinedState = useRouterState({\n select: (s) => {\n // First try to find match by props.matchId\n let match = s.matches.find((d) => d.id === props.matchId)\n\n // If match found, update lastKnownRouteId\n if (match) {\n lastKnownRouteId = match.routeId as string\n } else if (lastKnownRouteId) {\n // Match not found - props.matchId might be stale during a same-route transition\n // (matchId changed due to loaderDepsHash but props haven't updated yet)\n // Try to find the NEW match by routeId and use that instead\n const sameRouteMatch = s.matches.find(\n (d) => d.routeId === lastKnownRouteId,\n )\n if (sameRouteMatch) {\n match = sameRouteMatch\n }\n }\n\n if (!match) {\n // Route no longer exists - truly navigating away\n return null\n }\n\n const routeId = match.routeId as string\n\n // Compute remount key\n const remountFn =\n (router.routesById[routeId] as AnyRoute).options.remountDeps ??\n router.options.defaultRemountDeps\n\n let remountKey: string | undefined\n if (remountFn) {\n const remountDeps = remountFn({\n routeId,\n loaderDeps: match.loaderDeps,\n params: match._strictParams,\n search: match._strictSearch,\n })\n remountKey = remountDeps ? JSON.stringify(remountDeps) : undefined\n }\n\n return {\n routeId,\n match: {\n id: match.id,\n status: match.status,\n error: match.error,\n ssr: match.ssr,\n _forcePending: match._forcePending,\n _displayPending: match._displayPending,\n },\n remountKey,\n }\n },\n })\n\n const route = Vue.computed(() => {\n if (!combinedState.value) return null\n return router.routesById[combinedState.value.routeId]!\n })\n\n const match = Vue.computed(() => combinedState.value?.match)\n const remountKey = Vue.computed(() => combinedState.value?.remountKey)\n\n return (): VNode | null => {\n // If match doesn't exist, return null (component is being unmounted or not ready)\n if (!combinedState.value || !match.value || !route.value) return null\n\n // Handle different match statuses\n if (match.value._displayPending) {\n const PendingComponent =\n route.value.options.pendingComponent ??\n router.options.defaultPendingComponent\n\n return PendingComponent ? Vue.h(PendingComponent) : null\n }\n\n if (match.value._forcePending) {\n const PendingComponent =\n route.value.options.pendingComponent ??\n router.options.defaultPendingComponent\n\n return PendingComponent ? Vue.h(PendingComponent) : null\n }\n\n if (match.value.status === 'notFound') {\n invariant(isNotFound(match.value.error), 'Expected a notFound error')\n return renderRouteNotFound(router, route.value, match.value.error)\n }\n\n if (match.value.status === 'redirected') {\n invariant(isRedirect(match.value.error), 'Expected a redirect error')\n throw router.getMatch(match.value.id)?._nonReactive.loadPromise\n }\n\n if (match.value.status === 'error') {\n // Check if this route or any parent has an error component\n const RouteErrorComponent =\n route.value.options.errorComponent ??\n router.options.defaultErrorComponent\n\n // If this route has an error component, render it directly\n // This is more reliable than relying on Vue's error boundary\n if (RouteErrorComponent) {\n return Vue.h(RouteErrorComponent, {\n error: match.value.error,\n reset: () => {\n router.invalidate()\n },\n info: {\n componentStack: '',\n },\n })\n }\n\n // If there's no error component for this route, throw the error\n // so it can bubble up to the nearest parent with an error component\n throw match.value.error\n }\n\n if (match.value.status === 'pending') {\n const pendingMinMs =\n route.value.options.pendingMinMs ?? router.options.defaultPendingMinMs\n\n const routerMatch = router.getMatch(match.value.id)\n if (\n pendingMinMs &&\n routerMatch &&\n !routerMatch._nonReactive.minPendingPromise\n ) {\n // Create a promise that will resolve after the minPendingMs\n if (!router.isServer) {\n const minPendingPromise = createControlledPromise<void>()\n\n routerMatch._nonReactive.minPendingPromise = minPendingPromise\n\n setTimeout(() => {\n minPendingPromise.resolve()\n // We've handled the minPendingPromise, so we can delete it\n routerMatch._nonReactive.minPendingPromise = undefined\n }, pendingMinMs)\n }\n }\n\n // In Vue, we render the pending component directly instead of throwing a promise\n // because Vue's Suspense doesn't catch thrown promises like React does\n const PendingComponent =\n route.value.options.pendingComponent ??\n router.options.defaultPendingComponent\n\n if (PendingComponent) {\n return Vue.h(PendingComponent)\n }\n\n // If no pending component, return null while loading\n return null\n }\n\n // Success status - render the component with remount key\n const Comp =\n route.value.options.component ?? router.options.defaultComponent\n const key = remountKey.value\n\n if (Comp) {\n // Pass key as a prop - Vue.h properly handles 'key' as a special prop\n return Vue.h(Comp, key !== undefined ? { key } : undefined)\n }\n\n return Vue.h(Outlet, key !== undefined ? { key } : undefined)\n }\n },\n})\n\nexport const Outlet = Vue.defineComponent({\n name: 'Outlet',\n setup() {\n const router = useRouter()\n const matchId = Vue.inject(matchContext)\n const safeMatchId = Vue.computed(() => matchId?.value || '')\n\n const routeId = useRouterState({\n select: (s) =>\n s.matches.find((d) => d.id === safeMatchId.value)?.routeId as string,\n })\n\n const route = Vue.computed(() => router.routesById[routeId.value]!)\n\n const parentGlobalNotFound = useRouterState({\n select: (s) => {\n const matches = s.matches\n const parentMatch = matches.find((d) => d.id === safeMatchId.value)\n\n // During navigation transitions, parent match can be temporarily removed\n // Return false to avoid errors - the component will handle this gracefully\n if (!parentMatch) {\n return false\n }\n\n return parentMatch.globalNotFound\n },\n })\n\n const childMatchData = useRouterState({\n select: (s) => {\n const matches = s.matches\n const index = matches.findIndex((d) => d.id === safeMatchId.value)\n const child = matches[index + 1]\n if (!child) return null\n return {\n id: child.id,\n // Key based on routeId + params only (not loaderDeps)\n // This ensures component recreates when params change,\n // but NOT when only loaderDeps change\n paramsKey: child.routeId + JSON.stringify(child._strictParams),\n }\n },\n })\n\n return (): VNode | null => {\n if (parentGlobalNotFound.value) {\n return renderRouteNotFound(router, route.value, undefined)\n }\n\n if (!childMatchData.value) {\n return null\n }\n\n const nextMatch = Vue.h(Match, {\n matchId: childMatchData.value.id,\n key: childMatchData.value.paramsKey,\n })\n\n if (safeMatchId.value === rootRouteId) {\n return Vue.h(\n Vue.Suspense,\n {\n fallback: router.options.defaultPendingComponent\n ? Vue.h(router.options.defaultPendingComponent)\n : null,\n },\n {\n default: () => nextMatch,\n },\n )\n }\n\n return nextMatch\n }\n },\n})\n"],"names":["Match","Vue","defineComponent","name","props","matchId","type","String","required","setup","router","useRouter","lastKnownRouteId","matchData","useRouterState","select","s","match","matches","find","d","id","matchIndex","findIndex","routeId","parentRouteId","loadedAt","ssr","_displayPending","invariant","value","route","computed","routesById","PendingComponent","options","pendingComponent","defaultPendingComponent","pendingElement","h","undefined","routeErrorComponent","errorComponent","defaultErrorComponent","routeOnCatch","onCatch","defaultOnCatch","routeNotFoundComponent","isRoot","notFoundComponent","notFoundRoute","component","hasShellComponent","shellComponent","ShellComponent","matchIdRef","ref","watch","propsMatchId","dataMatchId","immediate","provide","matchContext","actualMatchId","resolvedNoSsr","shouldClientOnly","renderMatchContent","matchInner","MatchInner","content","ClientOnly","fallback","default","CatchNotFound","error","children","CatchBoundary","getResetKey","ErrorComponent","isNotFound","warning","withScrollRestoration","rootRouteId","scrollRestoration","Fragment","OnRendered","ScrollRestoration","filter","Boolean","length","location","resolvedLocation","state","key","watchEffect","emit","getLocationChangeInfo","combinedState","sameRouteMatch","remountFn","remountDeps","defaultRemountDeps","remountKey","loaderDeps","params","_strictParams","search","_strictSearch","JSON","stringify","status","_forcePending","renderRouteNotFound","isRedirect","getMatch","_nonReactive","loadPromise","RouteErrorComponent","reset","invalidate","info","componentStack","pendingMinMs","defaultPendingMinMs","routerMatch","minPendingPromise","isServer","createControlledPromise","setTimeout","resolve","Comp","defaultComponent","Outlet","inject","safeMatchId","parentGlobalNotFound","parentMatch","globalNotFound","childMatchData","index","child","paramsKey","nextMatch","Suspense"],"mappings":"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"}
@@ -14,8 +14,7 @@ const ScriptOnce = Vue.defineComponent({
14
14
  if (router.isServer) {
15
15
  return () => createVNode("script", {
16
16
  "nonce": router.options.ssr?.nonce,
17
- "class": "$tsr",
18
- "innerHTML": props.children
17
+ "innerHTML": props.children + ";document.currentScript.remove()"
19
18
  }, null);
20
19
  }
21
20
  const mounted = Vue.ref(false);
@@ -28,7 +27,6 @@ const ScriptOnce = Vue.defineComponent({
28
27
  }
29
28
  return createVNode("script", {
30
29
  "nonce": router.options.ssr?.nonce,
31
- "class": "$tsr",
32
30
  "data-allow-mismatch": true,
33
31
  "innerHTML": ""
34
32
  }, null);
@@ -1 +1 @@
1
- {"version":3,"file":"ScriptOnce.js","sources":["../../src/ScriptOnce.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport { useRouter } from './useRouter'\n\nexport const ScriptOnce = Vue.defineComponent({\n name: 'ScriptOnce',\n props: {\n children: {\n type: String,\n required: true,\n },\n },\n setup(props) {\n const router = useRouter()\n\n if (router.isServer) {\n return () => (\n <script\n nonce={router.options.ssr?.nonce}\n class=\"$tsr\"\n innerHTML={props.children}\n />\n )\n }\n\n const mounted = Vue.ref(false)\n Vue.onMounted(() => {\n mounted.value = true\n })\n\n return () => {\n if (mounted.value) {\n return null\n }\n\n return (\n <script\n nonce={router.options.ssr?.nonce}\n class=\"$tsr\"\n data-allow-mismatch\n innerHTML=\"\"\n />\n )\n }\n },\n})\n"],"names":["ScriptOnce","Vue","defineComponent","name","props","children","type","String","required","setup","router","useRouter","isServer","_createVNode","options","ssr","nonce","mounted","ref","onMounted","value"],"mappings":";;;MAGaA,aAAaC,IAAIC,gBAAgB;AAAA,EAC5CC,MAAM;AAAA,EACNC,OAAO;AAAA,IACLC,UAAU;AAAA,MACRC,MAAMC;AAAAA,MACNC,UAAU;AAAA,IACZ;AAAA;EAEFC,MAAML,OAAO;AACX,UAAMM,SAASC,UAAS;AAExB,QAAID,OAAOE,UAAU;AACnB,aAAO,MAAAC,YAAA,UAAA;AAAA,QAAA,SAEIH,OAAOI,QAAQC,KAAKC;AAAAA,QAAK,SAAA;AAAA,QAAA,aAErBZ,MAAMC;AAAAA,SAAQ,IAAA;AAAA,IAG/B;AAEA,UAAMY,UAAUhB,IAAIiB,IAAI,KAAK;AAC7BjB,QAAIkB,UAAU,MAAM;AAClBF,cAAQG,QAAQ;AAAA,IAClB,CAAC;AAED,WAAO,MAAM;AACX,UAAIH,QAAQG,OAAO;AACjB,eAAO;AAAA,MACT;AAEA,aAAAP,YAAA,UAAA;AAAA,QAAA,SAEWH,OAAOI,QAAQC,KAAKC;AAAAA,QAAK,SAAA;AAAA,QAAA,uBAAA;AAAA,QAAA,aAAA;AAAA,MAAA,GAAA,IAAA;AAAA,IAMtC;AAAA,EACF;AACF,CAAC;"}
1
+ {"version":3,"file":"ScriptOnce.js","sources":["../../src/ScriptOnce.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport { useRouter } from './useRouter'\n\nexport const ScriptOnce = Vue.defineComponent({\n name: 'ScriptOnce',\n props: {\n children: {\n type: String,\n required: true,\n },\n },\n setup(props) {\n const router = useRouter()\n\n if (router.isServer) {\n return () => (\n <script\n nonce={router.options.ssr?.nonce}\n innerHTML={props.children + ';document.currentScript.remove()'}\n />\n )\n }\n\n const mounted = Vue.ref(false)\n Vue.onMounted(() => {\n mounted.value = true\n })\n\n return () => {\n if (mounted.value) {\n return null\n }\n\n return (\n <script\n nonce={router.options.ssr?.nonce}\n data-allow-mismatch\n innerHTML=\"\"\n />\n )\n }\n },\n})\n"],"names":["ScriptOnce","Vue","defineComponent","name","props","children","type","String","required","setup","router","useRouter","isServer","_createVNode","options","ssr","nonce","mounted","ref","onMounted","value"],"mappings":";;;MAGaA,aAAaC,IAAIC,gBAAgB;AAAA,EAC5CC,MAAM;AAAA,EACNC,OAAO;AAAA,IACLC,UAAU;AAAA,MACRC,MAAMC;AAAAA,MACNC,UAAU;AAAA,IACZ;AAAA;EAEFC,MAAML,OAAO;AACX,UAAMM,SAASC,UAAS;AAExB,QAAID,OAAOE,UAAU;AACnB,aAAO,MAAAC,YAAA,UAAA;AAAA,QAAA,SAEIH,OAAOI,QAAQC,KAAKC;AAAAA,QAAK,aACrBZ,MAAMC,WAAW;AAAA,SAAkC,IAAA;AAAA,IAGpE;AAEA,UAAMY,UAAUhB,IAAIiB,IAAI,KAAK;AAC7BjB,QAAIkB,UAAU,MAAM;AAClBF,cAAQG,QAAQ;AAAA,IAClB,CAAC;AAED,WAAO,MAAM;AACX,UAAIH,QAAQG,OAAO;AACjB,eAAO;AAAA,MACT;AAEA,aAAAP,YAAA,UAAA;AAAA,QAAA,SAEWH,OAAOI,QAAQC,KAAKC;AAAAA,QAAK,uBAAA;AAAA,QAAA,aAAA;AAAA,MAAA,GAAA,IAAA;AAAA,IAKtC;AAAA,EACF;AACF,CAAC;"}
@@ -3,7 +3,6 @@ import { createVNode, Fragment, mergeProps } from "vue";
3
3
  import { Asset } from "./Asset.js";
4
4
  import { useRouterState } from "./useRouterState.js";
5
5
  import { useRouter } from "./useRouter.js";
6
- const VUE_DEFER_SCRIPT = "self.$_TSR_DEFER=true";
7
6
  const Scripts = Vue.defineComponent({
8
7
  name: "Scripts",
9
8
  setup() {
@@ -51,13 +50,6 @@ const Scripts = Vue.defineComponent({
51
50
  return () => {
52
51
  const allScripts = [];
53
52
  if (router.serverSsr) {
54
- allScripts.push({
55
- tag: "script",
56
- attrs: {
57
- nonce
58
- },
59
- children: VUE_DEFER_SCRIPT
60
- });
61
53
  const serverBufferedScript = router.serverSsr.takeBufferedScripts();
62
54
  if (serverBufferedScript) {
63
55
  allScripts.push(serverBufferedScript);
@@ -75,7 +67,6 @@ const Scripts = Vue.defineComponent({
75
67
  tag: "script",
76
68
  attrs: {
77
69
  nonce,
78
- class: "$tsr",
79
70
  id: "$tsr-stream-barrier",
80
71
  "data-allow-mismatch": true
81
72
  },
@@ -1 +1 @@
1
- {"version":3,"file":"Scripts.js","sources":["../../src/Scripts.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport { Asset } from './Asset'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\n// Script that sets the defer flag for Vue - must run BEFORE TSR bootstrap script\n// This prevents $_TSR.c() from removing scripts until Vue hydration is complete\nconst VUE_DEFER_SCRIPT = 'self.$_TSR_DEFER=true'\n\nexport const Scripts = Vue.defineComponent({\n name: 'Scripts',\n setup() {\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n\n const assetScripts = useRouterState({\n select: (state) => {\n const assetScripts: Array<RouterManagedTag> = []\n const manifest = router.ssr?.manifest\n\n if (!manifest) {\n return []\n }\n\n state.matches\n .map((match) => router.looseRoutesById[match.routeId]!)\n .forEach((route) =>\n manifest.routes[route.id]?.assets\n ?.filter((d) => d.tag === 'script')\n .forEach((asset) => {\n assetScripts.push({\n tag: 'script',\n attrs: { ...asset.attrs, nonce },\n children: asset.children,\n } as RouterManagedTag)\n }),\n )\n\n return assetScripts\n },\n })\n\n const scripts = useRouterState({\n select: (state) => ({\n scripts: (\n state.matches\n .map((match) => match.scripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script' as const,\n attrs: {\n ...script,\n nonce,\n },\n children,\n })),\n }),\n })\n\n const mounted = Vue.ref(false)\n Vue.onMounted(() => {\n mounted.value = true\n })\n\n return () => {\n const allScripts: Array<RouterManagedTag> = []\n\n if (router.serverSsr) {\n allScripts.push({\n tag: 'script',\n attrs: { nonce },\n children: VUE_DEFER_SCRIPT,\n } as RouterManagedTag)\n\n const serverBufferedScript = router.serverSsr.takeBufferedScripts()\n if (serverBufferedScript) {\n allScripts.push(serverBufferedScript)\n }\n } else if (router.ssr && !mounted.value) {\n allScripts.push({\n tag: 'script',\n attrs: { nonce, 'data-allow-mismatch': true },\n children: '',\n } as RouterManagedTag)\n\n allScripts.push({\n tag: 'script',\n attrs: {\n nonce,\n class: '$tsr',\n id: '$tsr-stream-barrier',\n 'data-allow-mismatch': true,\n },\n children: '',\n } as RouterManagedTag)\n\n for (const asset of assetScripts.value) {\n allScripts.push({\n tag: 'script',\n attrs: {\n ...asset.attrs,\n 'data-allow-mismatch': true,\n },\n children: '',\n } as RouterManagedTag)\n }\n }\n\n for (const script of scripts.value.scripts) {\n allScripts.push(script as RouterManagedTag)\n }\n\n if (mounted.value || router.serverSsr) {\n for (const asset of assetScripts.value) {\n allScripts.push(asset)\n }\n }\n\n return (\n <>\n {allScripts.map((asset, i) => (\n <Asset {...asset} key={`tsr-scripts-${asset.tag}-${i}`} />\n ))}\n </>\n )\n }\n },\n})\n"],"names":["VUE_DEFER_SCRIPT","Scripts","Vue","defineComponent","name","setup","router","useRouter","nonce","options","ssr","assetScripts","useRouterState","select","state","manifest","matches","map","match","looseRoutesById","routeId","forEach","route","routes","id","assets","filter","d","tag","asset","push","attrs","children","scripts","flat","Boolean","script","mounted","ref","onMounted","value","allScripts","serverSsr","serverBufferedScript","takeBufferedScripts","class","_createVNode","_Fragment","i","Asset","_mergeProps"],"mappings":";;;;;AAQA,MAAMA,mBAAmB;MAEZC,UAAUC,IAAIC,gBAAgB;AAAA,EACzCC,MAAM;AAAA,EACNC,QAAQ;AACN,UAAMC,SAASC,UAAS;AACxB,UAAMC,QAAQF,OAAOG,QAAQC,KAAKF;AAElC,UAAMG,eAAeC,eAAe;AAAA,MAClCC,QAASC,WAAU;AACjB,cAAMH,gBAAwC,CAAA;AAC9C,cAAMI,WAAWT,OAAOI,KAAKK;AAE7B,YAAI,CAACA,UAAU;AACb,iBAAO,CAAA;AAAA,QACT;AAEAD,cAAME,QACHC,IAAKC,WAAUZ,OAAOa,gBAAgBD,MAAME,OAAO,CAAE,EACrDC,QAASC,WACRP,SAASQ,OAAOD,MAAME,EAAE,GAAGC,QACvBC,OAAQC,OAAMA,EAAEC,QAAQ,QAAQ,EACjCP,QAASQ,WAAU;AAClBlB,UAAAA,cAAamB,KAAK;AAAA,YAChBF,KAAK;AAAA,YACLG,OAAO;AAAA,cAAE,GAAGF,MAAME;AAAAA,cAAOvB;AAAAA;YACzBwB,UAAUH,MAAMG;AAAAA,UAClB,CAAqB;AAAA,QACvB,CAAC,CACL;AAEF,eAAOrB;AAAAA,MACT;AAAA,IACF,CAAC;AAED,UAAMsB,UAAUrB,eAAe;AAAA,MAC7BC,QAASC,YAAW;AAAA,QAClBmB,SACEnB,MAAME,QACHC,IAAKC,WAAUA,MAAMe,OAAQ,EAC7BC,KAAK,CAAC,EACNR,OAAOS,OAAO,EACjBlB,IAAI,CAAC;AAAA,UAAEe;AAAAA,UAAU,GAAGI;AAAAA,QAAO,OAAO;AAAA,UAClCR,KAAK;AAAA,UACLG,OAAO;AAAA,YACL,GAAGK;AAAAA,YACH5B;AAAAA;UAEFwB;AAAAA,QACF,EAAE;AAAA;IAEN,CAAC;AAED,UAAMK,UAAUnC,IAAIoC,IAAI,KAAK;AAC7BpC,QAAIqC,UAAU,MAAM;AAClBF,cAAQG,QAAQ;AAAA,IAClB,CAAC;AAED,WAAO,MAAM;AACX,YAAMC,aAAsC,CAAA;AAE5C,UAAInC,OAAOoC,WAAW;AACpBD,mBAAWX,KAAK;AAAA,UACdF,KAAK;AAAA,UACLG,OAAO;AAAA,YAAEvB;AAAAA;UACTwB,UAAUhC;AAAAA,QACZ,CAAqB;AAErB,cAAM2C,uBAAuBrC,OAAOoC,UAAUE,oBAAmB;AACjE,YAAID,sBAAsB;AACxBF,qBAAWX,KAAKa,oBAAoB;AAAA,QACtC;AAAA,MACF,WAAWrC,OAAOI,OAAO,CAAC2B,QAAQG,OAAO;AACvCC,mBAAWX,KAAK;AAAA,UACdF,KAAK;AAAA,UACLG,OAAO;AAAA,YAAEvB;AAAAA,YAAO,uBAAuB;AAAA;UACvCwB,UAAU;AAAA,QACZ,CAAqB;AAErBS,mBAAWX,KAAK;AAAA,UACdF,KAAK;AAAA,UACLG,OAAO;AAAA,YACLvB;AAAAA,YACAqC,OAAO;AAAA,YACPrB,IAAI;AAAA,YACJ,uBAAuB;AAAA;UAEzBQ,UAAU;AAAA,QACZ,CAAqB;AAErB,mBAAWH,SAASlB,aAAa6B,OAAO;AACtCC,qBAAWX,KAAK;AAAA,YACdF,KAAK;AAAA,YACLG,OAAO;AAAA,cACL,GAAGF,MAAME;AAAAA,cACT,uBAAuB;AAAA;YAEzBC,UAAU;AAAA,UACZ,CAAqB;AAAA,QACvB;AAAA,MACF;AAEA,iBAAWI,UAAUH,QAAQO,MAAMP,SAAS;AAC1CQ,mBAAWX,KAAKM,MAA0B;AAAA,MAC5C;AAEA,UAAIC,QAAQG,SAASlC,OAAOoC,WAAW;AACrC,mBAAWb,SAASlB,aAAa6B,OAAO;AACtCC,qBAAWX,KAAKD,KAAK;AAAA,QACvB;AAAA,MACF;AAEA,aAAAiB,YAAAC,iBAEKN,WAAWxB,IAAI,CAACY,OAAOmB,MAACF,YAAAG,OAAAC,WACZrB,OAAK;AAAA,QAAA,OAAO,eAAeA,MAAMD,GAAG,IAAIoB,CAAC;AAAA,MAAE,CAAA,GAAA,IAAA,CACvD,CAAC,CAAA;AAAA,IAGR;AAAA,EACF;AACF,CAAC;"}
1
+ {"version":3,"file":"Scripts.js","sources":["../../src/Scripts.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport { Asset } from './Asset'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\nexport const Scripts = Vue.defineComponent({\n name: 'Scripts',\n setup() {\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n\n const assetScripts = useRouterState({\n select: (state) => {\n const assetScripts: Array<RouterManagedTag> = []\n const manifest = router.ssr?.manifest\n\n if (!manifest) {\n return []\n }\n\n state.matches\n .map((match) => router.looseRoutesById[match.routeId]!)\n .forEach((route) =>\n manifest.routes[route.id]?.assets\n ?.filter((d) => d.tag === 'script')\n .forEach((asset) => {\n assetScripts.push({\n tag: 'script',\n attrs: { ...asset.attrs, nonce },\n children: asset.children,\n } as RouterManagedTag)\n }),\n )\n\n return assetScripts\n },\n })\n\n const scripts = useRouterState({\n select: (state) => ({\n scripts: (\n state.matches\n .map((match) => match.scripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script' as const,\n attrs: {\n ...script,\n nonce,\n },\n children,\n })),\n }),\n })\n\n const mounted = Vue.ref(false)\n Vue.onMounted(() => {\n mounted.value = true\n })\n\n return () => {\n const allScripts: Array<RouterManagedTag> = []\n\n if (router.serverSsr) {\n const serverBufferedScript = router.serverSsr.takeBufferedScripts()\n if (serverBufferedScript) {\n allScripts.push(serverBufferedScript)\n }\n } else if (router.ssr && !mounted.value) {\n allScripts.push({\n tag: 'script',\n attrs: { nonce, 'data-allow-mismatch': true },\n children: '',\n } as RouterManagedTag)\n\n allScripts.push({\n tag: 'script',\n attrs: {\n nonce,\n id: '$tsr-stream-barrier',\n 'data-allow-mismatch': true,\n },\n children: '',\n } as RouterManagedTag)\n\n for (const asset of assetScripts.value) {\n allScripts.push({\n tag: 'script',\n attrs: {\n ...asset.attrs,\n 'data-allow-mismatch': true,\n },\n children: '',\n } as RouterManagedTag)\n }\n }\n\n for (const script of scripts.value.scripts) {\n allScripts.push(script as RouterManagedTag)\n }\n\n if (mounted.value || router.serverSsr) {\n for (const asset of assetScripts.value) {\n allScripts.push(asset)\n }\n }\n\n return (\n <>\n {allScripts.map((asset, i) => (\n <Asset {...asset} key={`tsr-scripts-${asset.tag}-${i}`} />\n ))}\n </>\n )\n }\n },\n})\n"],"names":["Scripts","Vue","defineComponent","name","setup","router","useRouter","nonce","options","ssr","assetScripts","useRouterState","select","state","manifest","matches","map","match","looseRoutesById","routeId","forEach","route","routes","id","assets","filter","d","tag","asset","push","attrs","children","scripts","flat","Boolean","script","mounted","ref","onMounted","value","allScripts","serverSsr","serverBufferedScript","takeBufferedScripts","_createVNode","_Fragment","i","Asset","_mergeProps"],"mappings":"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"}
@@ -50,8 +50,13 @@ function useTransitionerSetup() {
50
50
  fn();
51
51
  endTransition();
52
52
  };
53
+ const originalStartViewTransition = router.__tsrOriginalStartViewTransition ?? router.startViewTransition;
54
+ router.__tsrOriginalStartViewTransition = originalStartViewTransition;
53
55
  router.startViewTransition = (fn) => {
54
- fn();
56
+ return originalStartViewTransition?.(async () => {
57
+ await fn();
58
+ await Vue.nextTick();
59
+ });
55
60
  };
56
61
  let unsubscribe;
57
62
  Vue.onMounted(() => {
@@ -74,6 +79,13 @@ function useTransitionerSetup() {
74
79
  const isMounted = Vue.ref(false);
75
80
  Vue.onMounted(() => {
76
81
  isMounted.value = true;
82
+ if (!isAnyPending.value) {
83
+ router.__store.setState((s) => s.status === "pending" ? {
84
+ ...s,
85
+ status: "idle",
86
+ resolvedLocation: s.location
87
+ } : s);
88
+ }
77
89
  });
78
90
  Vue.onUnmounted(() => {
79
91
  isMounted.value = false;
@@ -125,17 +137,19 @@ function useTransitionerSetup() {
125
137
  Vue.watch(isAnyPending, (newValue) => {
126
138
  if (!isMounted.value) return;
127
139
  try {
140
+ if (!newValue && router.__store.state.status === "pending") {
141
+ router.__store.setState((s) => ({
142
+ ...s,
143
+ status: "idle",
144
+ resolvedLocation: s.location
145
+ }));
146
+ }
128
147
  if (previousIsAnyPending.value.previous && !newValue) {
129
148
  const changeInfo = getLocationChangeInfo(router.state);
130
149
  router.emit({
131
150
  type: "onResolved",
132
151
  ...changeInfo
133
152
  });
134
- router.__store.setState((s) => ({
135
- ...s,
136
- status: "idle",
137
- resolvedLocation: s.location
138
- }));
139
153
  if (changeInfo.hrefChanged) {
140
154
  handleHashScroll(router);
141
155
  }