@tanstack/vue-router 1.170.6 → 1.170.8

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.
@@ -12,9 +12,9 @@ export declare const HeadContent: Vue.DefineComponent<Vue.ExtractPropTypes<{
12
12
  type: Vue.PropType<AssetCrossOriginConfig>;
13
13
  default: undefined;
14
14
  };
15
- }>, () => Vue.VNode<Vue.RendererNode, Vue.RendererElement, {
15
+ }>, () => (Vue.VNode<Vue.RendererNode, Vue.RendererElement, {
16
16
  [key: string]: any;
17
- }>[], {}, {}, {}, Vue.ComponentOptionsMixin, Vue.ComponentOptionsMixin, {}, string, Vue.PublicProps, Readonly<Vue.ExtractPropTypes<{
17
+ }> | null)[], {}, {}, {}, Vue.ComponentOptionsMixin, Vue.ComponentOptionsMixin, {}, string, Vue.PublicProps, Readonly<Vue.ExtractPropTypes<{
18
18
  assetCrossOrigin: {
19
19
  type: Vue.PropType<AssetCrossOriginConfig>;
20
20
  default: undefined;
@@ -1,9 +1,9 @@
1
1
  import { useHydrated } from "./ClientOnly.js";
2
2
  import { Asset } from "./Asset.js";
3
3
  import { useTags } from "./headContentUtils.js";
4
+ import { DEV_STYLES_ATTR } from "@tanstack/router-core";
4
5
  import * as Vue from "vue";
5
6
  //#region src/HeadContent.dev.tsx
6
- var DEV_STYLES_ATTR = "data-tanstack-router-dev-styles";
7
7
  /**
8
8
  * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.
9
9
  * It should be rendered in the `<head>` of your document.
@@ -23,7 +23,7 @@ var HeadContent = Vue.defineComponent({
23
23
  document.querySelectorAll(`link[${DEV_STYLES_ATTR}]`).forEach((el) => el.remove());
24
24
  });
25
25
  return () => {
26
- return (hydrated.value ? tags().filter((tag) => !tag.attrs?.[DEV_STYLES_ATTR]) : tags()).map((tag) => Vue.h(Asset, {
26
+ return (hydrated.value ? tags().filter((tag) => tag.tag !== "link" || tag.attrs?.[DEV_STYLES_ATTR] !== true) : tags()).map((tag) => Vue.h(Asset, {
27
27
  ...tag,
28
28
  key: `tsr-meta-${JSON.stringify(tag)}`
29
29
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"HeadContent.dev.js","names":["Vue","Asset","useHydrated","useTags","DEV_STYLES_ATTR","HeadContent","defineComponent","name","props","assetCrossOrigin","type","String","Object","default","undefined","setup","tags","hydrated","onMounted","document","querySelectorAll","forEach","el","remove","filteredTags","value","filter","tag","attrs","map","h","key","JSON","stringify"],"sources":["../../src/HeadContent.dev.tsx"],"sourcesContent":["import * as Vue from 'vue'\n\nimport { Asset } from './Asset'\nimport { useHydrated } from './ClientOnly'\nimport { useTags } from './headContentUtils'\nimport type { AssetCrossOriginConfig } from '@tanstack/router-core'\n\nconst DEV_STYLES_ATTR = 'data-tanstack-router-dev-styles'\n\n/**\n * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.\n * It should be rendered in the `<head>` of your document.\n *\n * This is the development version that filters out dev styles after hydration.\n */\nexport const HeadContent = Vue.defineComponent({\n name: 'HeadContent',\n props: {\n assetCrossOrigin: {\n type: [String, Object] as Vue.PropType<AssetCrossOriginConfig>,\n default: undefined,\n },\n },\n setup(props) {\n const tags = useTags(props.assetCrossOrigin)\n const hydrated = useHydrated()\n\n // Fallback cleanup for hydration mismatch cases\n Vue.onMounted(() => {\n document\n .querySelectorAll(`link[${DEV_STYLES_ATTR}]`)\n .forEach((el) => el.remove())\n })\n\n return () => {\n // Filter out dev styles after hydration\n const filteredTags = hydrated.value\n ? tags().filter((tag) => !tag.attrs?.[DEV_STYLES_ATTR])\n : tags()\n\n return filteredTags.map((tag) =>\n Vue.h(Asset, {\n ...tag,\n key: `tsr-meta-${JSON.stringify(tag)}`,\n }),\n )\n }\n },\n})\n"],"mappings":";;;;;AAOA,IAAMI,kBAAkB;;;;;;;AAQxB,IAAaC,cAAcL,IAAIM,gBAAgB;CAC7CC,MAAM;CACNC,OAAO,EACLC,kBAAkB;EAChBC,MAAM,CAACC,QAAQC,OAA+C;EAC9DC,SAASC,KAAAA;EACX,EACD;CACDC,MAAMP,OAAO;EACX,MAAMQ,OAAOb,QAAQK,MAAMC,iBAAiB;EAC5C,MAAMQ,WAAWf,aAAa;AAG9BF,MAAIkB,gBAAgB;AAClBC,YACGC,iBAAiB,QAAQhB,gBAAe,GAAI,CAC5CiB,SAASC,OAAOA,GAAGC,QAAQ,CAAC;IAC/B;AAEF,eAAa;AAMX,WAJqBN,SAASQ,QAC1BT,MAAM,CAACU,QAAQC,QAAQ,CAACA,IAAIC,QAAQxB,iBAAiB,GACrDY,MAAM,EAEUa,KAAKF,QACvB3B,IAAI8B,EAAE7B,OAAO;IACX,GAAG0B;IACHI,KAAK,YAAYC,KAAKC,UAAUN,IAAI;IACrC,CACH,CAAC;;;CAGN,CAAC"}
1
+ {"version":3,"file":"HeadContent.dev.js","names":["Vue","DEV_STYLES_ATTR","Asset","useHydrated","useTags","HeadContent","defineComponent","name","props","assetCrossOrigin","type","String","Object","default","undefined","setup","tags","hydrated","onMounted","document","querySelectorAll","forEach","el","remove","filteredTags","value","filter","tag","attrs","map","h","key","JSON","stringify"],"sources":["../../src/HeadContent.dev.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport { DEV_STYLES_ATTR } from '@tanstack/router-core'\n\nimport { Asset } from './Asset'\nimport { useHydrated } from './ClientOnly'\nimport { useTags } from './headContentUtils'\nimport type { AssetCrossOriginConfig } from '@tanstack/router-core'\n\n/**\n * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.\n * It should be rendered in the `<head>` of your document.\n *\n * This is the development version that filters out dev styles after hydration.\n */\nexport const HeadContent = Vue.defineComponent({\n name: 'HeadContent',\n props: {\n assetCrossOrigin: {\n type: [String, Object] as Vue.PropType<AssetCrossOriginConfig>,\n default: undefined,\n },\n },\n setup(props) {\n const tags = useTags(props.assetCrossOrigin)\n const hydrated = useHydrated()\n\n // Fallback cleanup for hydration mismatch cases\n Vue.onMounted(() => {\n document\n .querySelectorAll(`link[${DEV_STYLES_ATTR}]`)\n .forEach((el) => el.remove())\n })\n\n return () => {\n // Filter out dev styles after hydration\n const filteredTags = hydrated.value\n ? tags().filter(\n (tag) =>\n tag.tag !== 'link' || tag.attrs?.[DEV_STYLES_ATTR] !== true,\n )\n : tags()\n\n return filteredTags.map((tag) =>\n Vue.h(Asset, {\n ...tag,\n key: `tsr-meta-${JSON.stringify(tag)}`,\n }),\n )\n }\n },\n})\n"],"mappings":";;;;;;;;;;;;AAcA,IAAaK,cAAcL,IAAIM,gBAAgB;CAC7CC,MAAM;CACNC,OAAO,EACLC,kBAAkB;EAChBC,MAAM,CAACC,QAAQC,OAA+C;EAC9DC,SAASC,KAAAA;EACX,EACD;CACDC,MAAMP,OAAO;EACX,MAAMQ,OAAOZ,QAAQI,MAAMC,iBAAiB;EAC5C,MAAMQ,WAAWd,aAAa;AAG9BH,MAAIkB,gBAAgB;AAClBC,YACGC,iBAAiB,QAAQnB,gBAAe,GAAI,CAC5CoB,SAASC,OAAOA,GAAGC,QAAQ,CAAC;IAC/B;AAEF,eAAa;AASX,WAPqBN,SAASQ,QAC1BT,MAAM,CAACU,QACJC,QACCA,IAAIA,QAAQ,UAAUA,IAAIC,QAAQ3B,qBAAqB,KAC1D,GACDe,MAAM,EAEUa,KAAKF,QACvB3B,IAAI8B,EAAE5B,OAAO;IACX,GAAGyB;IACHI,KAAK,YAAYC,KAAKC,UAAUN,IAAI;IACrC,CACH,CAAC;;;CAGN,CAAC"}
@@ -1,7 +1,56 @@
1
+ import { useRouter } from "./useRouter.js";
1
2
  import { Asset } from "./Asset.js";
2
3
  import { useTags } from "./headContentUtils.js";
3
4
  import * as Vue from "vue";
5
+ import { isServer } from "@tanstack/router-core/isServer";
4
6
  //#region src/HeadContent.tsx
7
+ function attrsMatch(attrs, element) {
8
+ let expectedAttrCount = 0;
9
+ for (const name in attrs) {
10
+ const value = attrs[name];
11
+ if (value === void 0 || value === false || value === null) continue;
12
+ expectedAttrCount++;
13
+ const attrName = name.toLowerCase();
14
+ if (value === true) {
15
+ if (!element.hasAttribute(attrName)) return false;
16
+ continue;
17
+ }
18
+ if (element.getAttribute(attrName) !== String(value)) return false;
19
+ }
20
+ return expectedAttrCount === element.attributes.length;
21
+ }
22
+ function reconcileHydratedHead(tags, preservedHeadTagElements) {
23
+ if (typeof document === "undefined") return;
24
+ const matchedHeadElements = /* @__PURE__ */ new Set();
25
+ const hydratedLinks = document.head.querySelectorAll("link");
26
+ for (const tag of tags) {
27
+ if (tag.tag !== "link") continue;
28
+ const attrs = tag.attrs;
29
+ const rel = typeof attrs?.rel === "string" ? attrs.rel.toLowerCase() : void 0;
30
+ if (rel !== "stylesheet" && rel !== "preload" && rel !== "modulepreload") continue;
31
+ for (const element of hydratedLinks) if (!matchedHeadElements.has(element) && attrsMatch(attrs, element)) {
32
+ matchedHeadElements.add(element);
33
+ const key = JSON.stringify(tag);
34
+ (preservedHeadTagElements[key] ||= []).push(element);
35
+ break;
36
+ }
37
+ }
38
+ }
39
+ function cleanupInactivePreservedHeadElements(preservedHeadTagElements, activeElements) {
40
+ for (const key in preservedHeadTagElements) {
41
+ const elements = preservedHeadTagElements[key];
42
+ let nextElements;
43
+ for (const element of elements) if (activeElements.has(element)) (nextElements ||= []).push(element);
44
+ else if (!shouldRemoveInactivePreservedHeadElement(element)) (nextElements ||= []).push(element);
45
+ else element.remove();
46
+ if (nextElements) preservedHeadTagElements[key] = nextElements;
47
+ else delete preservedHeadTagElements[key];
48
+ }
49
+ }
50
+ function shouldRemoveInactivePreservedHeadElement(element) {
51
+ const rel = element.getAttribute("rel")?.toLowerCase();
52
+ return rel === "preload" || rel === "modulepreload";
53
+ }
5
54
  /**
6
55
  * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.
7
56
  * It should be rendered in the `<head>` of your document.
@@ -13,12 +62,43 @@ var HeadContent = Vue.defineComponent({
13
62
  default: void 0
14
63
  } },
15
64
  setup(props) {
65
+ const router = useRouter();
16
66
  const tags = useTags(props.assetCrossOrigin);
67
+ if (isServer ?? router.isServer) return () => {
68
+ return tags().map((tag) => {
69
+ const key = JSON.stringify(tag);
70
+ return Vue.h(Asset, {
71
+ ...tag,
72
+ key: `tsr-meta-${key}`
73
+ });
74
+ });
75
+ };
76
+ const preservedHeadTagElements = {};
77
+ let activePreservedHeadElements = /* @__PURE__ */ new Set();
78
+ if (router.ssr) reconcileHydratedHead(tags(), preservedHeadTagElements);
79
+ Vue.onUpdated(() => {
80
+ cleanupInactivePreservedHeadElements(preservedHeadTagElements, activePreservedHeadElements);
81
+ });
82
+ Vue.onUnmounted(() => {
83
+ cleanupInactivePreservedHeadElements(preservedHeadTagElements, /* @__PURE__ */ new Set());
84
+ });
17
85
  return () => {
18
- return tags().map((tag) => Vue.h(Asset, {
19
- ...tag,
20
- key: `tsr-meta-${JSON.stringify(tag)}`
21
- }));
86
+ const renderedPreservedHeadTagKeys = {};
87
+ activePreservedHeadElements = /* @__PURE__ */ new Set();
88
+ return tags().map((tag) => {
89
+ const key = JSON.stringify(tag);
90
+ const renderedCount = renderedPreservedHeadTagKeys[key] || 0;
91
+ const preservedElement = preservedHeadTagElements[key]?.[renderedCount];
92
+ if (preservedElement?.isConnected) {
93
+ renderedPreservedHeadTagKeys[key] = renderedCount + 1;
94
+ activePreservedHeadElements.add(preservedElement);
95
+ return null;
96
+ }
97
+ return Vue.h(Asset, {
98
+ ...tag,
99
+ key: `tsr-meta-${key}`
100
+ });
101
+ });
22
102
  };
23
103
  }
24
104
  });
@@ -1 +1 @@
1
- {"version":3,"file":"HeadContent.js","names":["Vue","Asset","useTags","HeadContent","defineComponent","name","props","assetCrossOrigin","type","String","Object","default","undefined","setup","tags","map","tag","h","key","JSON","stringify"],"sources":["../../src/HeadContent.tsx"],"sourcesContent":["import * as Vue from 'vue'\n\nimport { Asset } from './Asset'\nimport { useTags } from './headContentUtils'\nimport type { AssetCrossOriginConfig } from '@tanstack/router-core'\n\nexport interface HeadContentProps {\n assetCrossOrigin?: AssetCrossOriginConfig\n}\n\n/**\n * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.\n * It should be rendered in the `<head>` of your document.\n */\nexport const HeadContent = Vue.defineComponent({\n name: 'HeadContent',\n props: {\n assetCrossOrigin: {\n type: [String, Object] as Vue.PropType<AssetCrossOriginConfig>,\n default: undefined,\n },\n },\n setup(props) {\n const tags = useTags(props.assetCrossOrigin)\n\n return () => {\n return tags().map((tag) =>\n Vue.h(Asset, {\n ...tag,\n key: `tsr-meta-${JSON.stringify(tag)}`,\n }),\n )\n }\n },\n})\n"],"mappings":";;;;;;;;AAcA,IAAaG,cAAcH,IAAII,gBAAgB;CAC7CC,MAAM;CACNC,OAAO,EACLC,kBAAkB;EAChBC,MAAM,CAACC,QAAQC,OAA+C;EAC9DC,SAASC,KAAAA;EACX,EACD;CACDC,MAAMP,OAAO;EACX,MAAMQ,OAAOZ,QAAQI,MAAMC,iBAAiB;AAE5C,eAAa;AACX,UAAOO,MAAM,CAACC,KAAKC,QACjBhB,IAAIiB,EAAEhB,OAAO;IACX,GAAGe;IACHE,KAAK,YAAYC,KAAKC,UAAUJ,IAAI;IACrC,CACH,CAAC;;;CAGN,CAAC"}
1
+ {"version":3,"file":"HeadContent.js","names":["Vue","isServer","Asset","useTags","useRouter","attrsMatch","attrs","element","expectedAttrCount","name","value","undefined","attrName","toLowerCase","hasAttribute","getAttribute","String","attributes","length","reconcileHydratedHead","tags","preservedHeadTagElements","document","matchedHeadElements","Set","hydratedLinks","head","querySelectorAll","tag","rel","has","add","key","JSON","stringify","push","cleanupInactivePreservedHeadElements","activeElements","elements","nextElements","shouldRemoveInactivePreservedHeadElement","remove","HeadContent","defineComponent","props","assetCrossOrigin","type","Object","default","setup","router","map","h","activePreservedHeadElements","ssr","onUpdated","onUnmounted","renderedPreservedHeadTagKeys","renderedTags","renderedCount","preservedElement","isConnected"],"sources":["../../src/HeadContent.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport { isServer } from '@tanstack/router-core/isServer'\n\nimport { Asset } from './Asset'\nimport { useTags } from './headContentUtils'\nimport { useRouter } from './useRouter'\nimport type {\n AssetCrossOriginConfig,\n RouterManagedTag,\n} from '@tanstack/router-core'\n\nfunction attrsMatch(attrs: Record<string, any>, element: Element) {\n let expectedAttrCount = 0\n\n for (const name in attrs) {\n const value = attrs[name]\n if (value === undefined || value === false || value === null) {\n continue\n }\n\n expectedAttrCount++\n const attrName = name.toLowerCase()\n\n if (value === true) {\n if (!element.hasAttribute(attrName)) {\n return false\n }\n\n continue\n }\n\n if (element.getAttribute(attrName) !== String(value)) {\n return false\n }\n }\n\n return expectedAttrCount === element.attributes.length\n}\n\nfunction reconcileHydratedHead(\n tags: Array<RouterManagedTag>,\n preservedHeadTagElements: Record<string, Array<Element>>,\n) {\n if (typeof document === 'undefined') {\n return\n }\n\n const matchedHeadElements = new Set<Element>()\n const hydratedLinks = document.head.querySelectorAll('link')\n\n for (const tag of tags) {\n if (tag.tag !== 'link') {\n continue\n }\n\n const attrs = tag.attrs\n const rel =\n typeof attrs?.rel === 'string' ? attrs.rel.toLowerCase() : undefined\n if (rel !== 'stylesheet' && rel !== 'preload' && rel !== 'modulepreload') {\n continue\n }\n\n for (const element of hydratedLinks) {\n if (!matchedHeadElements.has(element) && attrsMatch(attrs!, element)) {\n matchedHeadElements.add(element)\n const key = JSON.stringify(tag)\n ;(preservedHeadTagElements[key] ||= []).push(element)\n break\n }\n }\n }\n}\n\nfunction cleanupInactivePreservedHeadElements(\n preservedHeadTagElements: Record<string, Array<Element>>,\n activeElements: Set<Element>,\n) {\n for (const key in preservedHeadTagElements) {\n const elements = preservedHeadTagElements[key]!\n let nextElements: Array<Element> | undefined\n\n for (const element of elements) {\n if (activeElements.has(element)) {\n ;(nextElements ||= []).push(element)\n } else if (!shouldRemoveInactivePreservedHeadElement(element)) {\n ;(nextElements ||= []).push(element)\n } else {\n element.remove()\n }\n }\n\n if (nextElements) {\n preservedHeadTagElements[key] = nextElements\n } else {\n delete preservedHeadTagElements[key]\n }\n }\n}\n\nfunction shouldRemoveInactivePreservedHeadElement(element: Element) {\n const rel = element.getAttribute('rel')?.toLowerCase()\n return rel === 'preload' || rel === 'modulepreload'\n}\n\nexport interface HeadContentProps {\n assetCrossOrigin?: AssetCrossOriginConfig\n}\n\n/**\n * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.\n * It should be rendered in the `<head>` of your document.\n */\nexport const HeadContent = Vue.defineComponent({\n name: 'HeadContent',\n props: {\n assetCrossOrigin: {\n type: [String, Object] as Vue.PropType<AssetCrossOriginConfig>,\n default: undefined,\n },\n },\n setup(props) {\n const router = useRouter()\n const tags = useTags(props.assetCrossOrigin)\n\n if (isServer ?? router.isServer) {\n return () => {\n return tags().map((tag) => {\n const key = JSON.stringify(tag)\n return Vue.h(Asset, {\n ...tag,\n key: `tsr-meta-${key}`,\n })\n })\n }\n }\n\n const preservedHeadTagElements: Record<string, Array<Element>> = {}\n let activePreservedHeadElements = new Set<Element>()\n\n if (router.ssr) {\n reconcileHydratedHead(tags(), preservedHeadTagElements)\n }\n\n Vue.onUpdated(() => {\n cleanupInactivePreservedHeadElements(\n preservedHeadTagElements,\n activePreservedHeadElements,\n )\n })\n Vue.onUnmounted(() => {\n cleanupInactivePreservedHeadElements(\n preservedHeadTagElements,\n new Set<Element>(),\n )\n })\n\n return () => {\n const renderedPreservedHeadTagKeys: Record<string, number> = {}\n activePreservedHeadElements = new Set<Element>()\n const renderedTags = tags().map((tag) => {\n const key = JSON.stringify(tag)\n const renderedCount = renderedPreservedHeadTagKeys[key] || 0\n const preservedElement = preservedHeadTagElements[key]?.[renderedCount]\n if (preservedElement?.isConnected) {\n renderedPreservedHeadTagKeys[key] = renderedCount + 1\n activePreservedHeadElements.add(preservedElement)\n return null\n }\n\n return Vue.h(Asset, {\n ...tag,\n key: `tsr-meta-${key}`,\n })\n })\n\n return renderedTags\n }\n },\n})\n"],"mappings":"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"}
@@ -2,6 +2,7 @@ import { useRouter } from "./useRouter.js";
2
2
  import { Asset } from "./Asset.js";
3
3
  import * as Vue from "vue";
4
4
  import { Fragment, createVNode, mergeProps } from "vue";
5
+ import { isServer } from "@tanstack/router-core/isServer";
5
6
  import { useStore } from "@tanstack/vue-store";
6
7
  //#region src/Scripts.tsx
7
8
  var Scripts = Vue.defineComponent({
@@ -10,72 +11,82 @@ var Scripts = Vue.defineComponent({
10
11
  const router = useRouter();
11
12
  const nonce = router.options.ssr?.nonce;
12
13
  const matches = useStore(router.stores.matches, (value) => value);
13
- const assetScripts = Vue.computed(() => {
14
+ const getAssetScripts = (matches) => {
14
15
  const assetScripts = [];
15
16
  const manifest = router.ssr?.manifest;
16
17
  if (!manifest) return [];
17
- matches.value.map((match) => router.looseRoutesById[match.routeId]).forEach((route) => manifest.routes[route.id]?.assets?.filter((d) => d.tag === "script").forEach((asset) => {
18
- assetScripts.push({
19
- tag: "script",
20
- attrs: {
21
- ...asset.attrs,
22
- nonce
23
- },
24
- children: asset.children
18
+ matches.forEach((match) => {
19
+ manifest.routes[match.routeId]?.scripts?.forEach((asset) => {
20
+ assetScripts.push({
21
+ tag: "script",
22
+ attrs: {
23
+ ...asset.attrs,
24
+ nonce
25
+ },
26
+ children: asset.children
27
+ });
25
28
  });
26
- }));
29
+ });
27
30
  return assetScripts;
28
- });
29
- const scripts = Vue.computed(() => ({ scripts: matches.value.map((match) => match.scripts).flat(1).filter(Boolean).map(({ children, ...script }) => ({
31
+ };
32
+ const getScripts = (matches) => matches.map((match) => match.scripts).flat(1).filter(Boolean).map(({ children, ...script }) => ({
30
33
  tag: "script",
31
34
  attrs: {
32
35
  ...script,
33
36
  nonce
34
37
  },
35
38
  children
36
- })) }));
39
+ }));
40
+ const assetScripts = Vue.computed(() => getAssetScripts(matches.value));
41
+ const scripts = Vue.computed(() => getScripts(matches.value));
37
42
  const mounted = Vue.ref(false);
38
43
  Vue.onMounted(() => {
39
44
  mounted.value = true;
40
45
  });
41
- return () => {
42
- const allScripts = [];
43
- if (router.serverSsr) {
44
- const serverBufferedScript = router.serverSsr.takeBufferedScripts();
45
- if (serverBufferedScript) allScripts.push(serverBufferedScript);
46
- } else if (router.ssr && !mounted.value) {
47
- allScripts.push({
48
- tag: "script",
49
- attrs: {
50
- nonce,
51
- "data-allow-mismatch": true
52
- },
53
- children: ""
54
- });
55
- allScripts.push({
56
- tag: "script",
57
- attrs: {
58
- nonce,
59
- id: "$tsr-stream-barrier",
60
- "data-allow-mismatch": true
61
- },
62
- children: ""
63
- });
64
- for (const asset of assetScripts.value) allScripts.push({
65
- tag: "script",
66
- attrs: {
67
- ...asset.attrs,
68
- "data-allow-mismatch": true
69
- },
70
- children: ""
71
- });
72
- }
73
- for (const script of scripts.value.scripts) allScripts.push(script);
74
- if (mounted.value || router.serverSsr) for (const asset of assetScripts.value) allScripts.push(asset);
75
- return createVNode(Fragment, null, [allScripts.map((asset, i) => createVNode(Asset, mergeProps(asset, { "key": `tsr-scripts-${asset.tag}-${i}` }), null))]);
76
- };
46
+ return () => renderScripts(router, {
47
+ scripts: scripts.value,
48
+ assetScripts: assetScripts.value,
49
+ mounted: mounted.value,
50
+ nonce
51
+ });
77
52
  }
78
53
  });
54
+ function renderScripts(router, { scripts, assetScripts, mounted, nonce }) {
55
+ const allScripts = [];
56
+ if ((isServer ?? router.isServer) && router.serverSsr) {
57
+ const serverBufferedScript = router.serverSsr.takeBufferedScripts();
58
+ if (serverBufferedScript) allScripts.push(serverBufferedScript);
59
+ } else if (router.ssr && !mounted) {
60
+ allScripts.push({
61
+ tag: "script",
62
+ attrs: {
63
+ nonce,
64
+ "data-allow-mismatch": true
65
+ },
66
+ children: ""
67
+ });
68
+ allScripts.push({
69
+ tag: "script",
70
+ attrs: {
71
+ nonce,
72
+ id: "$tsr-stream-barrier",
73
+ "data-allow-mismatch": true
74
+ },
75
+ children: ""
76
+ });
77
+ for (const asset of assetScripts) allScripts.push({
78
+ tag: "script",
79
+ attrs: {
80
+ ...asset.attrs,
81
+ "data-allow-mismatch": true
82
+ },
83
+ children: ""
84
+ });
85
+ }
86
+ allScripts.push(...scripts);
87
+ if (mounted || (isServer ?? router.isServer) && router.serverSsr) allScripts.push(...assetScripts);
88
+ return createVNode(Fragment, null, [allScripts.map((asset, i) => createVNode(Asset, mergeProps(asset, { "key": `tsr-scripts-${asset.tag}-${i}` }), null))]);
89
+ }
79
90
  //#endregion
80
91
  export { Scripts };
81
92
 
@@ -1 +1 @@
1
- {"version":3,"file":"Scripts.js","names":["Vue","useStore","Asset","useRouter","Scripts","defineComponent","name","setup","router","nonce","options","ssr","matches","stores","value","assetScripts","computed","manifest","map","match","looseRoutesById","routeId","forEach","route","routes","id","assets","filter","d","tag","asset","push","attrs","children","scripts","flat","Boolean","script","mounted","ref","onMounted","allScripts","serverSsr","serverBufferedScript","takeBufferedScripts","_createVNode","_Fragment","i","_mergeProps"],"sources":["../../src/Scripts.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport { useStore } from '@tanstack/vue-store'\nimport { Asset } from './Asset'\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 const matches = useStore(router.stores.matches, (value) => value)\n\n const assetScripts = Vue.computed<Array<RouterManagedTag>>(() => {\n const assetScripts: Array<RouterManagedTag> = []\n const manifest = router.ssr?.manifest\n\n if (!manifest) {\n return []\n }\n\n matches.value\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 const scripts = Vue.computed(() => ({\n scripts: (\n matches.value\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 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"],"mappings":";;;;;;AAMA,IAAaI,UAAUJ,IAAIK,gBAAgB;CACzCC,MAAM;CACNC,QAAQ;EACN,MAAMC,SAASL,WAAW;EAC1B,MAAMM,QAAQD,OAAOE,QAAQC,KAAKF;EAClC,MAAMG,UAAUX,SAASO,OAAOK,OAAOD,UAAUE,UAAUA,MAAM;EAEjE,MAAMC,eAAef,IAAIgB,eAAwC;GAC/D,MAAMD,eAAwC,EAAE;GAChD,MAAME,WAAWT,OAAOG,KAAKM;AAE7B,OAAI,CAACA,SACH,QAAO,EAAE;AAGXL,WAAQE,MACLI,KAAKC,UAAUX,OAAOY,gBAAgBD,MAAME,SAAU,CACtDC,SAASC,UACRN,SAASO,OAAOD,MAAME,KAAKC,QACvBC,QAAQC,MAAMA,EAAEC,QAAQ,SAAS,CAClCP,SAASQ,UAAU;AAClBf,iBAAagB,KAAK;KAChBF,KAAK;KACLG,OAAO;MAAE,GAAGF,MAAME;MAAOvB;MAAO;KAChCwB,UAAUH,MAAMG;KACG,CAAC;KAE5B,CAAC;AAEH,UAAOlB;IACP;EAEF,MAAMmB,UAAUlC,IAAIgB,gBAAgB,EAClCkB,SACEtB,QAAQE,MACLI,KAAKC,UAAUA,MAAMe,QAAS,CAC9BC,KAAK,EAAE,CACPR,OAAOS,QAAQ,CAClBlB,KAAK,EAAEe,UAAU,GAAGI,cAAc;GAClCR,KAAK;GACLG,OAAO;IACL,GAAGK;IACH5B;IACD;GACDwB;GACD,EAAC,EACH,EAAE;EAEH,MAAMK,UAAUtC,IAAIuC,IAAI,MAAM;AAC9BvC,MAAIwC,gBAAgB;AAClBF,WAAQxB,QAAQ;IAChB;AAEF,eAAa;GACX,MAAM2B,aAAsC,EAAE;AAE9C,OAAIjC,OAAOkC,WAAW;IACpB,MAAMC,uBAAuBnC,OAAOkC,UAAUE,qBAAqB;AACnE,QAAID,qBACFF,YAAWV,KAAKY,qBAAqB;cAE9BnC,OAAOG,OAAO,CAAC2B,QAAQxB,OAAO;AACvC2B,eAAWV,KAAK;KACdF,KAAK;KACLG,OAAO;MAAEvB;MAAO,uBAAuB;MAAM;KAC7CwB,UAAU;KACS,CAAC;AAEtBQ,eAAWV,KAAK;KACdF,KAAK;KACLG,OAAO;MACLvB;MACAgB,IAAI;MACJ,uBAAuB;MACxB;KACDQ,UAAU;KACS,CAAC;AAEtB,SAAK,MAAMH,SAASf,aAAaD,MAC/B2B,YAAWV,KAAK;KACdF,KAAK;KACLG,OAAO;MACL,GAAGF,MAAME;MACT,uBAAuB;MACxB;KACDC,UAAU;KACS,CAAC;;AAI1B,QAAK,MAAMI,UAAUH,QAAQpB,MAAMoB,QACjCO,YAAWV,KAAKM,OAA2B;AAG7C,OAAIC,QAAQxB,SAASN,OAAOkC,UAC1B,MAAK,MAAMZ,SAASf,aAAaD,MAC/B2B,YAAWV,KAAKD,MAAM;AAI1B,UAAAe,YAAAC,UAAA,MAAA,CAEKL,WAAWvB,KAAKY,OAAOiB,MAACF,YAAA3C,OAAA8C,WACZlB,OAAK,EAAA,OAAO,eAAeA,MAAMD,IAAG,GAAIkB,KAAG,CAAA,EAAA,KACvD,CAAC,CAAA,CAAA;;;CAKX,CAAC"}
1
+ {"version":3,"file":"Scripts.js","names":["Vue","useStore","isServer","Asset","useRouter","Scripts","defineComponent","name","setup","router","nonce","options","ssr","matches","stores","value","getAssetScripts","assetScripts","manifest","forEach","match","routeManifest","routes","routeId","scripts","asset","push","tag","attrs","children","getScripts","map","flat","filter","Boolean","script","computed","mounted","ref","onMounted","renderScripts","allScripts","serverSsr","serverBufferedScript","takeBufferedScripts","id","_createVNode","_Fragment","i","_mergeProps"],"sources":["../../src/Scripts.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport { useStore } from '@tanstack/vue-store'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { Asset } from './Asset'\nimport { useRouter } from './useRouter'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\ntype ScriptsRenderState = {\n scripts: Array<RouterManagedTag>\n assetScripts: Array<RouterManagedTag>\n mounted: boolean\n nonce?: string\n}\n\nexport const Scripts = Vue.defineComponent({\n name: 'Scripts',\n setup() {\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n const matches = useStore(router.stores.matches, (value) => value)\n\n const getAssetScripts = (matches: Array<any>) => {\n const assetScripts: Array<RouterManagedTag> = []\n const manifest = router.ssr?.manifest\n\n if (!manifest) {\n return []\n }\n\n matches.forEach((match) => {\n const routeManifest = manifest.routes[match.routeId]\n\n routeManifest?.scripts?.forEach((asset) => {\n assetScripts.push({\n tag: 'script',\n attrs: { ...asset.attrs, nonce },\n children: asset.children,\n })\n })\n })\n\n return assetScripts\n }\n\n const getScripts = (matches: Array<any>): Array<RouterManagedTag> =>\n (\n matches\n .map((match) => match.scripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(\n ({ children, ...script }) =>\n ({\n tag: 'script',\n attrs: {\n ...script,\n nonce,\n },\n children,\n }) satisfies RouterManagedTag,\n )\n\n const assetScripts = Vue.computed<Array<RouterManagedTag>>(() =>\n getAssetScripts(matches.value),\n )\n const scripts = Vue.computed<Array<RouterManagedTag>>(() =>\n getScripts(matches.value),\n )\n\n const mounted = Vue.ref(false)\n Vue.onMounted(() => {\n mounted.value = true\n })\n\n return () =>\n renderScripts(router, {\n scripts: scripts.value,\n assetScripts: assetScripts.value,\n mounted: mounted.value,\n nonce,\n })\n },\n})\n\nfunction renderScripts(\n router: ReturnType<typeof useRouter>,\n { scripts, assetScripts, mounted, nonce }: ScriptsRenderState,\n) {\n const allScripts: Array<RouterManagedTag> = []\n\n if ((isServer ?? router.isServer) && router.serverSsr) {\n const serverBufferedScript = router.serverSsr.takeBufferedScripts()\n if (serverBufferedScript) {\n allScripts.push(serverBufferedScript)\n }\n } else if (router.ssr && !mounted) {\n allScripts.push({\n tag: 'script',\n attrs: { nonce, 'data-allow-mismatch': true },\n children: '',\n } satisfies 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 } satisfies RouterManagedTag)\n\n for (const asset of assetScripts) {\n allScripts.push({\n tag: 'script',\n attrs: {\n ...asset.attrs,\n 'data-allow-mismatch': true,\n },\n children: '',\n } satisfies RouterManagedTag)\n }\n }\n\n allScripts.push(...scripts)\n\n if (mounted || ((isServer ?? router.isServer) && router.serverSsr)) {\n allScripts.push(...assetScripts)\n }\n\n return (\n <>\n {allScripts.map((asset, i) => (\n <Asset {...asset} key={`tsr-scripts-${asset.tag}-${i}`} />\n ))}\n </>\n )\n}\n"],"mappings":";;;;;;;AAcA,IAAaK,UAAUL,IAAIM,gBAAgB;CACzCC,MAAM;CACNC,QAAQ;EACN,MAAMC,SAASL,WAAW;EAC1B,MAAMM,QAAQD,OAAOE,QAAQC,KAAKF;EAClC,MAAMG,UAAUZ,SAASQ,OAAOK,OAAOD,UAAUE,UAAUA,MAAM;EAEjE,MAAMC,mBAAmBH,YAAwB;GAC/C,MAAMI,eAAwC,EAAE;GAChD,MAAMC,WAAWT,OAAOG,KAAKM;AAE7B,OAAI,CAACA,SACH,QAAO,EAAE;AAGXL,WAAQM,SAASC,UAAU;AACHF,aAASI,OAAOF,MAAMG,UAE7BC,SAASL,SAASM,UAAU;AACzCR,kBAAaS,KAAK;MAChBC,KAAK;MACLC,OAAO;OAAE,GAAGH,MAAMG;OAAOlB;OAAO;MAChCmB,UAAUJ,MAAMI;MACjB,CAAC;MACF;KACF;AAEF,UAAOZ;;EAGT,MAAMa,cAAcjB,YAEhBA,QACGkB,KAAKX,UAAUA,MAAMI,QAAS,CAC9BQ,KAAK,EAAE,CACPC,OAAOC,QAAQ,CAClBH,KACC,EAAEF,UAAU,GAAGM,cACb;GACCR,KAAK;GACLC,OAAO;IACL,GAAGO;IACHzB;IACD;GACDmB;GACD,EACJ;EAEH,MAAMZ,eAAejB,IAAIoC,eACvBpB,gBAAgBH,QAAQE,MAC1B,CAAC;EACD,MAAMS,UAAUxB,IAAIoC,eAClBN,WAAWjB,QAAQE,MACrB,CAAC;EAED,MAAMsB,UAAUrC,IAAIsC,IAAI,MAAM;AAC9BtC,MAAIuC,gBAAgB;AAClBF,WAAQtB,QAAQ;IAChB;AAEF,eACEyB,cAAc/B,QAAQ;GACpBe,SAASA,QAAQT;GACjBE,cAAcA,aAAaF;GAC3BsB,SAASA,QAAQtB;GACjBL;GACD,CAAC;;CAEP,CAAC;AAEF,SAAS8B,cACP/B,QACA,EAAEe,SAASP,cAAcoB,SAAS3B,SAClC;CACA,MAAM+B,aAAsC,EAAE;AAE9C,MAAKvC,YAAYO,OAAOP,aAAaO,OAAOiC,WAAW;EACrD,MAAMC,uBAAuBlC,OAAOiC,UAAUE,qBAAqB;AACnE,MAAID,qBACFF,YAAWf,KAAKiB,qBAAqB;YAE9BlC,OAAOG,OAAO,CAACyB,SAAS;AACjCI,aAAWf,KAAK;GACdC,KAAK;GACLC,OAAO;IAAElB;IAAO,uBAAuB;IAAM;GAC7CmB,UAAU;GACgB,CAAC;AAE7BY,aAAWf,KAAK;GACdC,KAAK;GACLC,OAAO;IACLlB;IACAmC,IAAI;IACJ,uBAAuB;IACxB;GACDhB,UAAU;GACgB,CAAC;AAE7B,OAAK,MAAMJ,SAASR,aAClBwB,YAAWf,KAAK;GACdC,KAAK;GACLC,OAAO;IACL,GAAGH,MAAMG;IACT,uBAAuB;IACxB;GACDC,UAAU;GACgB,CAAC;;AAIjCY,YAAWf,KAAK,GAAGF,QAAQ;AAE3B,KAAIa,YAAanC,YAAYO,OAAOP,aAAaO,OAAOiC,UACtDD,YAAWf,KAAK,GAAGT,aAAa;AAGlC,QAAA6B,YAAAC,UAAA,MAAA,CAEKN,WAAWV,KAAKN,OAAOuB,MAACF,YAAA3C,OAAA8C,WACZxB,OAAK,EAAA,OAAO,eAAeA,MAAME,IAAG,GAAIqB,KAAG,CAAA,EAAA,KACvD,CAAC,CAAA,CAAA"}
@@ -1,3 +1,2 @@
1
1
  import { AssetCrossOriginConfig, RouterManagedTag } from '@tanstack/router-core';
2
2
  export declare const useTags: (assetCrossOrigin?: AssetCrossOriginConfig) => () => RouterManagedTag[];
3
- export declare function uniqBy<T>(arr: Array<T>, fn: (item: T) => string): T[];
@@ -1,5 +1,5 @@
1
1
  import { useRouter } from "./useRouter.js";
2
- import { escapeHtml, getAssetCrossOrigin, isInlinableStylesheet, resolveManifestAssetLink } from "@tanstack/router-core";
2
+ import { appendUniqueUserTags, escapeHtml, getAssetCrossOrigin, getScriptPreloadAttrs, resolveManifestCssLink } from "@tanstack/router-core";
3
3
  import * as Vue from "vue";
4
4
  import { useStore } from "@tanstack/vue-store";
5
5
  //#region src/headContentUtils.tsx
@@ -47,17 +47,14 @@ var useTags = (assetCrossOrigin) => {
47
47
  })));
48
48
  const preloadMeta = Vue.computed(() => {
49
49
  const preloadMeta = [];
50
- matches.value.map((match) => router.looseRoutesById[match.routeId]).forEach((route) => router.ssr?.manifest?.routes[route.id]?.preloads?.filter(Boolean).forEach((preload) => {
51
- const preloadLink = resolveManifestAssetLink(preload);
52
- preloadMeta.push({
53
- tag: "link",
54
- attrs: {
55
- rel: "modulepreload",
56
- href: preloadLink.href,
57
- crossOrigin: getAssetCrossOrigin(assetCrossOrigin, "modulepreload") ?? preloadLink.crossOrigin
58
- }
50
+ matches.value.forEach((match) => {
51
+ router.ssr?.manifest?.routes[match.routeId]?.preloads?.filter(Boolean).forEach((preload) => {
52
+ preloadMeta.push({
53
+ tag: "link",
54
+ attrs: { ...getScriptPreloadAttrs(router.ssr?.manifest, preload, assetCrossOrigin) }
55
+ });
59
56
  });
60
- }));
57
+ });
61
58
  return preloadMeta;
62
59
  });
63
60
  const headScripts = Vue.computed(() => matches.value.map((match) => match.headScripts).flat(1).filter(Boolean).map(({ children, ...script }) => ({
@@ -67,45 +64,38 @@ var useTags = (assetCrossOrigin) => {
67
64
  })));
68
65
  const manifestAssets = Vue.computed(() => {
69
66
  const manifest = router.ssr?.manifest;
70
- return matches.value.map((match) => manifest?.routes[match.routeId]?.assets ?? []).filter(Boolean).flat(1).flatMap((asset) => {
71
- if (asset.tag === "link") {
72
- if (isInlinableStylesheet(manifest, asset)) return [];
73
- return [{
67
+ const assets = [];
68
+ matches.value.forEach((match) => {
69
+ (manifest?.routes[match.routeId])?.css?.forEach((link) => {
70
+ const resolvedLink = resolveManifestCssLink(link);
71
+ assets.push({
74
72
  tag: "link",
75
73
  attrs: {
76
- ...asset.attrs,
77
- crossOrigin: getAssetCrossOrigin(assetCrossOrigin, "stylesheet") ?? asset.attrs?.crossOrigin
74
+ rel: "stylesheet",
75
+ ...resolvedLink,
76
+ crossOrigin: getAssetCrossOrigin(assetCrossOrigin, "stylesheet") ?? resolvedLink.crossOrigin
78
77
  }
79
- }];
80
- }
81
- if (asset.tag === "style") return [{
82
- tag: "style",
83
- attrs: asset.attrs,
84
- children: asset.children,
85
- ...asset.inlineCss ? { inlineCss: true } : {}
86
- }];
87
- return [];
78
+ });
79
+ });
88
80
  });
81
+ if (manifest?.inlineStyle) assets.push({
82
+ tag: "style",
83
+ attrs: manifest.inlineStyle.attrs,
84
+ children: manifest.inlineStyle.children,
85
+ inlineCss: true
86
+ });
87
+ return assets;
89
88
  });
90
- return () => uniqBy([
91
- ...manifestAssets.value,
92
- ...meta.value,
93
- ...preloadMeta.value,
94
- ...links.value,
95
- ...headScripts.value
96
- ], (d) => {
97
- return JSON.stringify(d);
98
- });
89
+ return () => {
90
+ const tags = [];
91
+ tags.push(...manifestAssets.value);
92
+ appendUniqueUserTags(tags, meta.value);
93
+ tags.push(...preloadMeta.value);
94
+ appendUniqueUserTags(tags, links.value);
95
+ appendUniqueUserTags(tags, headScripts.value);
96
+ return tags;
97
+ };
99
98
  };
100
- function uniqBy(arr, fn) {
101
- const seen = /* @__PURE__ */ new Set();
102
- return arr.filter((item) => {
103
- const key = fn(item);
104
- if (seen.has(key)) return false;
105
- seen.add(key);
106
- return true;
107
- });
108
- }
109
99
  //#endregion
110
100
  export { useTags };
111
101
 
@@ -1 +1 @@
1
- {"version":3,"file":"headContentUtils.js","names":["Vue","escapeHtml","getAssetCrossOrigin","isInlinableStylesheet","resolveManifestAssetLink","useStore","useRouter","useTags","assetCrossOrigin","router","matches","stores","value","meta","computed","resultMeta","metaByAttribute","title","map","match","filter","Boolean","reverse","forEach","metas","m","tag","children","json","JSON","stringify","push","attrs","type","attribute","name","property","links","flat","link","preloadMeta","looseRoutesById","routeId","route","ssr","manifest","routes","id","preloads","preload","preloadLink","rel","href","crossOrigin","headScripts","script","manifestAssets","assets","flatMap","asset","inlineCss","uniqBy","d","arr","fn","seen","Set","item","key","has","add"],"sources":["../../src/headContentUtils.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport {\n escapeHtml,\n getAssetCrossOrigin,\n isInlinableStylesheet,\n resolveManifestAssetLink,\n} from '@tanstack/router-core'\nimport { useStore } from '@tanstack/vue-store'\nimport { useRouter } from './useRouter'\nimport type {\n AssetCrossOriginConfig,\n RouterManagedTag,\n} from '@tanstack/router-core'\n\nexport const useTags = (assetCrossOrigin?: AssetCrossOriginConfig) => {\n const router = useRouter()\n const matches = useStore(router.stores.matches, (value) => value)\n\n const meta = Vue.computed<Array<RouterManagedTag>>(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n ;[...matches.value.map((match) => match.meta!).filter(Boolean)]\n .reverse()\n .forEach((metas) => {\n ;[...metas].reverse().forEach((m) => {\n if (!m) return\n\n if (m.title) {\n if (!title) {\n title = {\n tag: 'title',\n children: m.title,\n }\n }\n } else if ('script:ld+json' in m) {\n // Handle JSON-LD structured data\n // Content is HTML-escaped to prevent XSS when injected via innerHTML\n try {\n const json = JSON.stringify(m['script:ld+json'])\n resultMeta.push({\n tag: 'script',\n attrs: {\n type: 'application/ld+json',\n },\n children: escapeHtml(json),\n })\n } catch {\n // Skip invalid JSON-LD objects\n }\n } else {\n const attribute = m.name ?? m.property\n if (attribute) {\n if (metaByAttribute[attribute]) {\n return\n } else {\n metaByAttribute[attribute] = true\n }\n }\n\n resultMeta.push({\n tag: 'meta',\n attrs: {\n ...m,\n },\n })\n }\n })\n })\n\n if (title) {\n resultMeta.push(title)\n }\n\n resultMeta.reverse()\n\n return resultMeta\n })\n\n const links = Vue.computed<Array<RouterManagedTag>>(\n () =>\n matches.value\n .map((match) => match.links!)\n .filter(Boolean)\n .flat(1)\n .map((link) => ({\n tag: 'link',\n attrs: {\n ...link,\n },\n })) as Array<RouterManagedTag>,\n )\n\n const preloadMeta = Vue.computed<Array<RouterManagedTag>>(() => {\n const preloadMeta: Array<RouterManagedTag> = []\n\n matches.value\n .map((match) => router.looseRoutesById[match.routeId]!)\n .forEach((route) =>\n router.ssr?.manifest?.routes[route.id]?.preloads\n ?.filter(Boolean)\n .forEach((preload) => {\n const preloadLink = resolveManifestAssetLink(preload)\n preloadMeta.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preloadLink.href,\n crossOrigin:\n getAssetCrossOrigin(assetCrossOrigin, 'modulepreload') ??\n preloadLink.crossOrigin,\n },\n })\n }),\n )\n\n return preloadMeta\n })\n\n const headScripts = Vue.computed<Array<RouterManagedTag>>(() =>\n (\n matches.value\n .map((match) => match.headScripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script',\n attrs: {\n ...script,\n },\n children,\n })),\n )\n\n const manifestAssets = Vue.computed<Array<RouterManagedTag>>(() => {\n const manifest = router.ssr?.manifest\n\n const assets = matches.value\n .map((match) => manifest?.routes[match.routeId]?.assets ?? [])\n .filter(Boolean)\n .flat(1)\n .flatMap((asset): Array<RouterManagedTag> => {\n if (asset.tag === 'link') {\n if (isInlinableStylesheet(manifest, asset)) {\n return []\n }\n\n return [\n {\n tag: 'link',\n attrs: {\n ...asset.attrs,\n crossOrigin:\n getAssetCrossOrigin(assetCrossOrigin, 'stylesheet') ??\n asset.attrs?.crossOrigin,\n },\n },\n ]\n }\n\n if (asset.tag === 'style') {\n return [\n {\n tag: 'style',\n attrs: asset.attrs,\n children: asset.children,\n ...(asset.inlineCss ? { inlineCss: true as const } : {}),\n },\n ]\n }\n\n return []\n })\n\n return assets\n })\n\n return () =>\n uniqBy(\n [\n ...manifestAssets.value,\n ...meta.value,\n ...preloadMeta.value,\n ...links.value,\n ...headScripts.value,\n ] as Array<RouterManagedTag>,\n (d) => {\n return JSON.stringify(d)\n },\n )\n}\n\nexport function uniqBy<T>(arr: Array<T>, fn: (item: T) => string) {\n const seen = new Set<string>()\n return arr.filter((item) => {\n const key = fn(item)\n if (seen.has(key)) {\n return false\n }\n seen.add(key)\n return true\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"headContentUtils.js","names":["Vue","appendUniqueUserTags","escapeHtml","getAssetCrossOrigin","getScriptPreloadAttrs","resolveManifestCssLink","useStore","useRouter","useTags","assetCrossOrigin","router","matches","stores","value","meta","computed","resultMeta","metaByAttribute","title","map","match","filter","Boolean","reverse","forEach","metas","m","tag","children","json","JSON","stringify","push","attrs","type","attribute","name","property","links","flat","link","preloadMeta","ssr","manifest","routes","routeId","preloads","preload","headScripts","script","manifestAssets","assets","routeManifest","css","resolvedLink","rel","crossOrigin","inlineStyle","inlineCss","tags"],"sources":["../../src/headContentUtils.tsx"],"sourcesContent":["import * as Vue from 'vue'\nimport {\n appendUniqueUserTags,\n escapeHtml,\n getAssetCrossOrigin,\n getScriptPreloadAttrs,\n resolveManifestCssLink,\n} from '@tanstack/router-core'\nimport { useStore } from '@tanstack/vue-store'\nimport { useRouter } from './useRouter'\nimport type {\n AssetCrossOriginConfig,\n RouterManagedTag,\n} from '@tanstack/router-core'\n\nexport const useTags = (assetCrossOrigin?: AssetCrossOriginConfig) => {\n const router = useRouter()\n const matches = useStore(router.stores.matches, (value) => value)\n\n const meta = Vue.computed<Array<RouterManagedTag>>(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n ;[...matches.value.map((match) => match.meta!).filter(Boolean)]\n .reverse()\n .forEach((metas) => {\n ;[...metas].reverse().forEach((m) => {\n if (!m) return\n\n if (m.title) {\n if (!title) {\n title = {\n tag: 'title',\n children: m.title,\n }\n }\n } else if ('script:ld+json' in m) {\n // Handle JSON-LD structured data\n // Content is HTML-escaped to prevent XSS when injected via innerHTML\n try {\n const json = JSON.stringify(m['script:ld+json'])\n resultMeta.push({\n tag: 'script',\n attrs: {\n type: 'application/ld+json',\n },\n children: escapeHtml(json),\n })\n } catch {\n // Skip invalid JSON-LD objects\n }\n } else {\n const attribute = m.name ?? m.property\n if (attribute) {\n if (metaByAttribute[attribute]) {\n return\n } else {\n metaByAttribute[attribute] = true\n }\n }\n\n resultMeta.push({\n tag: 'meta',\n attrs: {\n ...m,\n },\n })\n }\n })\n })\n\n if (title) {\n resultMeta.push(title)\n }\n\n resultMeta.reverse()\n\n return resultMeta\n })\n\n const links = Vue.computed<Array<RouterManagedTag>>(\n () =>\n matches.value\n .map((match) => match.links!)\n .filter(Boolean)\n .flat(1)\n .map((link) => ({\n tag: 'link',\n attrs: {\n ...link,\n },\n })) as Array<RouterManagedTag>,\n )\n\n const preloadMeta = Vue.computed<Array<RouterManagedTag>>(() => {\n const preloadMeta: Array<RouterManagedTag> = []\n\n matches.value.forEach((match) => {\n router.ssr?.manifest?.routes[match.routeId]?.preloads\n ?.filter(Boolean)\n .forEach((preload) => {\n preloadMeta.push({\n tag: 'link',\n attrs: {\n ...getScriptPreloadAttrs(\n router.ssr?.manifest,\n preload,\n assetCrossOrigin,\n ),\n },\n })\n })\n })\n\n return preloadMeta\n })\n\n const headScripts = Vue.computed<Array<RouterManagedTag>>(() =>\n (\n matches.value\n .map((match) => match.headScripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script',\n attrs: {\n ...script,\n },\n children,\n })),\n )\n\n const manifestAssets = Vue.computed<Array<RouterManagedTag>>(() => {\n const manifest = router.ssr?.manifest\n\n const assets: Array<RouterManagedTag> = []\n\n matches.value.forEach((match) => {\n const routeManifest = manifest?.routes[match.routeId]\n\n routeManifest?.css?.forEach((link) => {\n const resolvedLink = resolveManifestCssLink(link)\n assets.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n ...resolvedLink,\n crossOrigin:\n getAssetCrossOrigin(assetCrossOrigin, 'stylesheet') ??\n resolvedLink.crossOrigin,\n },\n })\n })\n })\n\n if (manifest?.inlineStyle) {\n assets.push({\n tag: 'style',\n attrs: manifest.inlineStyle.attrs,\n children: manifest.inlineStyle.children,\n inlineCss: true,\n })\n }\n\n return assets\n })\n\n return () => {\n const tags: Array<RouterManagedTag> = []\n tags.push(...manifestAssets.value)\n appendUniqueUserTags(tags, meta.value)\n tags.push(...preloadMeta.value)\n appendUniqueUserTags(tags, links.value)\n appendUniqueUserTags(tags, headScripts.value)\n return tags\n }\n}\n"],"mappings":"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"}
@@ -12,9 +12,9 @@ export declare const HeadContent: Vue.DefineComponent<Vue.ExtractPropTypes<{
12
12
  type: Vue.PropType<AssetCrossOriginConfig>;
13
13
  default: undefined;
14
14
  };
15
- }>, () => Vue.VNode<Vue.RendererNode, Vue.RendererElement, {
15
+ }>, () => (Vue.VNode<Vue.RendererNode, Vue.RendererElement, {
16
16
  [key: string]: any;
17
- }>[], {}, {}, {}, Vue.ComponentOptionsMixin, Vue.ComponentOptionsMixin, {}, string, Vue.PublicProps, Readonly<Vue.ExtractPropTypes<{
17
+ }> | null)[], {}, {}, {}, Vue.ComponentOptionsMixin, Vue.ComponentOptionsMixin, {}, string, Vue.PublicProps, Readonly<Vue.ExtractPropTypes<{
18
18
  assetCrossOrigin: {
19
19
  type: Vue.PropType<AssetCrossOriginConfig>;
20
20
  default: undefined;
@@ -1,8 +1,8 @@
1
1
  import * as Vue from 'vue';
2
+ import { DEV_STYLES_ATTR } from '@tanstack/router-core';
2
3
  import { Asset } from './Asset';
3
4
  import { useHydrated } from './ClientOnly';
4
5
  import { useTags } from './headContentUtils';
5
- const DEV_STYLES_ATTR = 'data-tanstack-router-dev-styles';
6
6
  /**
7
7
  * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.
8
8
  * It should be rendered in the `<head>` of your document.
@@ -29,7 +29,7 @@ export const HeadContent = Vue.defineComponent({
29
29
  return () => {
30
30
  // Filter out dev styles after hydration
31
31
  const filteredTags = hydrated.value
32
- ? tags().filter((tag) => !tag.attrs?.[DEV_STYLES_ATTR])
32
+ ? tags().filter((tag) => tag.tag !== 'link' || tag.attrs?.[DEV_STYLES_ATTR] !== true)
33
33
  : tags();
34
34
  return filteredTags.map((tag) => Vue.h(Asset, {
35
35
  ...tag,
@@ -1 +1 @@
1
- {"version":3,"file":"HeadContent.dev.jsx","sourceRoot":"","sources":["../../src/HeadContent.dev.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAA;AAE1B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAG5C,MAAM,eAAe,GAAG,iCAAiC,CAAA;AAEzD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC,eAAe,CAAC;IAC7C,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE;QACL,gBAAgB,EAAE;YAChB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAyC;YAC9D,OAAO,EAAE,SAAS;SACnB;KACF;IACD,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAA;QAC5C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;QAE9B,gDAAgD;QAChD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,QAAQ;iBACL,gBAAgB,CAAC,QAAQ,eAAe,GAAG,CAAC;iBAC5C,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;QACjC,CAAC,CAAC,CAAA;QAEF,OAAO,GAAG,EAAE;YACV,wCAAwC;YACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK;gBACjC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,eAAe,CAAC,CAAC;gBACvD,CAAC,CAAC,IAAI,EAAE,CAAA;YAEV,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC9B,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE;gBACX,GAAG,GAAG;gBACN,GAAG,EAAE,YAAY,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE;aACvC,CAAC,CACH,CAAA;QACH,CAAC,CAAA;IACH,CAAC;CACF,CAAC,CAAA"}
1
+ {"version":3,"file":"HeadContent.dev.jsx","sourceRoot":"","sources":["../../src/HeadContent.dev.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAA;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAG5C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC,eAAe,CAAC;IAC7C,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE;QACL,gBAAgB,EAAE;YAChB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAyC;YAC9D,OAAO,EAAE,SAAS;SACnB;KACF;IACD,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAA;QAC5C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;QAE9B,gDAAgD;QAChD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,QAAQ;iBACL,gBAAgB,CAAC,QAAQ,eAAe,GAAG,CAAC;iBAC5C,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;QACjC,CAAC,CAAC,CAAA;QAEF,OAAO,GAAG,EAAE;YACV,wCAAwC;YACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK;gBACjC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,CACX,CAAC,GAAG,EAAE,EAAE,CACN,GAAG,CAAC,GAAG,KAAK,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC,eAAe,CAAC,KAAK,IAAI,CAC9D;gBACH,CAAC,CAAC,IAAI,EAAE,CAAA;YAEV,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC9B,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE;gBACX,GAAG,GAAG;gBACN,GAAG,EAAE,YAAY,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE;aACvC,CAAC,CACH,CAAA;QACH,CAAC,CAAA;IACH,CAAC;CACF,CAAC,CAAA"}