@tanstack/vue-router 1.146.2 → 1.147.1

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.
@@ -1,8 +1,26 @@
1
1
  import * as Vue from "vue";
2
- import { escapeHtml } from "@tanstack/router-core";
2
+ import { escapeHtml, buildDevStylesUrl } from "@tanstack/router-core";
3
3
  import { Asset } from "./Asset.js";
4
4
  import { useRouter } from "./useRouter.js";
5
5
  import { useRouterState } from "./useRouterState.js";
6
+ const DevStylesLink = Vue.defineComponent({
7
+ name: "DevStylesLink",
8
+ setup() {
9
+ const router = useRouter();
10
+ const routeIds = useRouterState({
11
+ select: (state) => state.matches.map((match) => match.routeId)
12
+ });
13
+ Vue.onMounted(() => {
14
+ document.querySelectorAll("[data-tanstack-start-dev-styles]").forEach((el) => el.remove());
15
+ });
16
+ const href = Vue.computed(() => buildDevStylesUrl(router.basepath, routeIds.value));
17
+ return () => Vue.h("link", {
18
+ rel: "stylesheet",
19
+ href: href.value,
20
+ "data-tanstack-start-dev-styles": true
21
+ });
22
+ }
23
+ });
6
24
  const useTags = () => {
7
25
  const router = useRouter();
8
26
  const routeMeta = useRouterState({
@@ -104,10 +122,14 @@ const HeadContent = Vue.defineComponent({
104
122
  setup() {
105
123
  const tags = useTags();
106
124
  return () => {
107
- return tags().map((tag) => Vue.h(Asset, {
125
+ const children = tags().map((tag) => Vue.h(Asset, {
108
126
  ...tag,
109
127
  key: `tsr-meta-${JSON.stringify(tag)}`
110
128
  }));
129
+ if (process.env.NODE_ENV !== "production") {
130
+ return [Vue.h(DevStylesLink), ...children];
131
+ }
132
+ return children;
111
133
  };
112
134
  }
113
135
  });
@@ -1 +1 @@
1
- {"version":3,"file":"HeadContent.js","sources":["../../src/HeadContent.tsx"],"sourcesContent":["import * as Vue from 'vue'\n\nimport { escapeHtml } from '@tanstack/router-core'\nimport { Asset } from './Asset'\nimport { useRouter } from './useRouter'\nimport { useRouterState } from './useRouterState'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\nexport const useTags = () => {\n const router = useRouter()\n\n const routeMeta = useRouterState({\n select: (state) => {\n return state.matches.map((match) => match.meta!).filter(Boolean)\n },\n })\n\n const meta: Vue.Ref<Array<RouterManagedTag>> = Vue.computed(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n ;[...routeMeta.value].reverse().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 = useRouterState({\n select: (state) =>\n state.matches\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 = useRouterState({\n select: (state) => {\n const preloadMeta: Array<RouterManagedTag> = []\n\n state.matches\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 preloadMeta.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n },\n })\n }),\n )\n\n return preloadMeta\n },\n })\n\n const headScripts = useRouterState({\n select: (state) =>\n (\n state.matches\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 return () =>\n uniqBy(\n [\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\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 setup() {\n const tags = useTags()\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\nfunction 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"],"names":["useTags","router","useRouter","routeMeta","useRouterState","select","state","matches","map","match","meta","filter","Boolean","Vue","computed","resultMeta","metaByAttribute","title","value","reverse","forEach","metas","m","tag","children","json","JSON","stringify","push","attrs","type","escapeHtml","attribute","name","property","links","flat","link","preloadMeta","looseRoutesById","routeId","route","ssr","manifest","routes","id","preloads","preload","rel","href","headScripts","script","uniqBy","d","HeadContent","defineComponent","setup","tags","h","Asset","key","arr","fn","seen","Set","item","has","add"],"mappings":"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"}
1
+ {"version":3,"file":"HeadContent.js","sources":["../../src/HeadContent.tsx"],"sourcesContent":["import * as Vue from 'vue'\n\nimport { buildDevStylesUrl, escapeHtml } from '@tanstack/router-core'\nimport { Asset } from './Asset'\nimport { useRouter } from './useRouter'\nimport { useRouterState } from './useRouterState'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\n/**\n * Renders a stylesheet link for dev mode CSS collection.\n * On the server, renders the full link with route-scoped CSS URL.\n * On the client, renders the same link to avoid hydration mismatch,\n * then removes it after hydration since Vite's HMR handles CSS updates.\n */\nconst DevStylesLink = Vue.defineComponent({\n name: 'DevStylesLink',\n setup() {\n const router = useRouter()\n const routeIds = useRouterState({\n select: (state) => state.matches.map((match) => match.routeId),\n })\n\n Vue.onMounted(() => {\n // After hydration, remove the SSR-rendered dev styles link\n document\n .querySelectorAll('[data-tanstack-start-dev-styles]')\n .forEach((el) => el.remove())\n })\n\n const href = Vue.computed(() =>\n buildDevStylesUrl(router.basepath, routeIds.value),\n )\n\n return () =>\n Vue.h('link', {\n rel: 'stylesheet',\n href: href.value,\n 'data-tanstack-start-dev-styles': true,\n })\n },\n})\n\nexport const useTags = () => {\n const router = useRouter()\n\n const routeMeta = useRouterState({\n select: (state) => {\n return state.matches.map((match) => match.meta!).filter(Boolean)\n },\n })\n\n const meta: Vue.Ref<Array<RouterManagedTag>> = Vue.computed(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n ;[...routeMeta.value].reverse().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 = useRouterState({\n select: (state) =>\n state.matches\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 = useRouterState({\n select: (state) => {\n const preloadMeta: Array<RouterManagedTag> = []\n\n state.matches\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 preloadMeta.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n },\n })\n }),\n )\n\n return preloadMeta\n },\n })\n\n const headScripts = useRouterState({\n select: (state) =>\n (\n state.matches\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 return () =>\n uniqBy(\n [\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\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 setup() {\n const tags = useTags()\n\n return () => {\n const children = tags().map((tag) =>\n Vue.h(Asset, {\n ...tag,\n key: `tsr-meta-${JSON.stringify(tag)}`,\n }),\n )\n\n // In dev mode, prepend the DevStylesLink\n if (process.env.NODE_ENV !== 'production') {\n return [Vue.h(DevStylesLink), ...children]\n }\n\n return children\n }\n },\n})\n\nfunction 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"],"names":["DevStylesLink","Vue","defineComponent","name","setup","router","useRouter","routeIds","useRouterState","select","state","matches","map","match","routeId","onMounted","document","querySelectorAll","forEach","el","remove","href","computed","buildDevStylesUrl","basepath","value","h","rel","useTags","routeMeta","meta","filter","Boolean","resultMeta","metaByAttribute","title","reverse","metas","m","tag","children","json","JSON","stringify","push","attrs","type","escapeHtml","attribute","property","links","flat","link","preloadMeta","looseRoutesById","route","ssr","manifest","routes","id","preloads","preload","headScripts","script","uniqBy","d","HeadContent","tags","Asset","key","process","env","NODE_ENV","arr","fn","seen","Set","item","has","add"],"mappings":"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"}
@@ -1,8 +1,35 @@
1
1
  import * as Vue from 'vue';
2
- import { escapeHtml } from '@tanstack/router-core';
2
+ import { buildDevStylesUrl, escapeHtml } from '@tanstack/router-core';
3
3
  import { Asset } from './Asset';
4
4
  import { useRouter } from './useRouter';
5
5
  import { useRouterState } from './useRouterState';
6
+ /**
7
+ * Renders a stylesheet link for dev mode CSS collection.
8
+ * On the server, renders the full link with route-scoped CSS URL.
9
+ * On the client, renders the same link to avoid hydration mismatch,
10
+ * then removes it after hydration since Vite's HMR handles CSS updates.
11
+ */
12
+ const DevStylesLink = Vue.defineComponent({
13
+ name: 'DevStylesLink',
14
+ setup() {
15
+ const router = useRouter();
16
+ const routeIds = useRouterState({
17
+ select: (state) => state.matches.map((match) => match.routeId),
18
+ });
19
+ Vue.onMounted(() => {
20
+ // After hydration, remove the SSR-rendered dev styles link
21
+ document
22
+ .querySelectorAll('[data-tanstack-start-dev-styles]')
23
+ .forEach((el) => el.remove());
24
+ });
25
+ const href = Vue.computed(() => buildDevStylesUrl(router.basepath, routeIds.value));
26
+ return () => Vue.h('link', {
27
+ rel: 'stylesheet',
28
+ href: href.value,
29
+ 'data-tanstack-start-dev-styles': true,
30
+ });
31
+ },
32
+ });
6
33
  export const useTags = () => {
7
34
  const router = useRouter();
8
35
  const routeMeta = useRouterState({
@@ -130,10 +157,15 @@ export const HeadContent = Vue.defineComponent({
130
157
  setup() {
131
158
  const tags = useTags();
132
159
  return () => {
133
- return tags().map((tag) => Vue.h(Asset, {
160
+ const children = tags().map((tag) => Vue.h(Asset, {
134
161
  ...tag,
135
162
  key: `tsr-meta-${JSON.stringify(tag)}`,
136
163
  }));
164
+ // In dev mode, prepend the DevStylesLink
165
+ if (process.env.NODE_ENV !== 'production') {
166
+ return [Vue.h(DevStylesLink), ...children];
167
+ }
168
+ return children;
137
169
  };
138
170
  },
139
171
  });
@@ -1 +1 @@
1
- {"version":3,"file":"HeadContent.jsx","sourceRoot":"","sources":["../../src/HeadContent.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"HeadContent.jsx","sourceRoot":"","sources":["../../src/HeadContent.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/vue-router",
3
- "version": "1.146.2",
3
+ "version": "1.147.1",
4
4
  "description": "Modern and scalable routing for Vue applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -63,7 +63,7 @@
63
63
  "tiny-invariant": "^1.3.3",
64
64
  "tiny-warning": "^1.0.3",
65
65
  "@tanstack/history": "1.145.7",
66
- "@tanstack/router-core": "1.146.2"
66
+ "@tanstack/router-core": "1.147.1"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@testing-library/jest-dom": "^6.6.3",
@@ -1,11 +1,45 @@
1
1
  import * as Vue from 'vue'
2
2
 
3
- import { escapeHtml } from '@tanstack/router-core'
3
+ import { buildDevStylesUrl, escapeHtml } from '@tanstack/router-core'
4
4
  import { Asset } from './Asset'
5
5
  import { useRouter } from './useRouter'
6
6
  import { useRouterState } from './useRouterState'
7
7
  import type { RouterManagedTag } from '@tanstack/router-core'
8
8
 
9
+ /**
10
+ * Renders a stylesheet link for dev mode CSS collection.
11
+ * On the server, renders the full link with route-scoped CSS URL.
12
+ * On the client, renders the same link to avoid hydration mismatch,
13
+ * then removes it after hydration since Vite's HMR handles CSS updates.
14
+ */
15
+ const DevStylesLink = Vue.defineComponent({
16
+ name: 'DevStylesLink',
17
+ setup() {
18
+ const router = useRouter()
19
+ const routeIds = useRouterState({
20
+ select: (state) => state.matches.map((match) => match.routeId),
21
+ })
22
+
23
+ Vue.onMounted(() => {
24
+ // After hydration, remove the SSR-rendered dev styles link
25
+ document
26
+ .querySelectorAll('[data-tanstack-start-dev-styles]')
27
+ .forEach((el) => el.remove())
28
+ })
29
+
30
+ const href = Vue.computed(() =>
31
+ buildDevStylesUrl(router.basepath, routeIds.value),
32
+ )
33
+
34
+ return () =>
35
+ Vue.h('link', {
36
+ rel: 'stylesheet',
37
+ href: href.value,
38
+ 'data-tanstack-start-dev-styles': true,
39
+ })
40
+ },
41
+ })
42
+
9
43
  export const useTags = () => {
10
44
  const router = useRouter()
11
45
 
@@ -152,12 +186,19 @@ export const HeadContent = Vue.defineComponent({
152
186
  const tags = useTags()
153
187
 
154
188
  return () => {
155
- return tags().map((tag) =>
189
+ const children = tags().map((tag) =>
156
190
  Vue.h(Asset, {
157
191
  ...tag,
158
192
  key: `tsr-meta-${JSON.stringify(tag)}`,
159
193
  }),
160
194
  )
195
+
196
+ // In dev mode, prepend the DevStylesLink
197
+ if (process.env.NODE_ENV !== 'production') {
198
+ return [Vue.h(DevStylesLink), ...children]
199
+ }
200
+
201
+ return children
161
202
  }
162
203
  },
163
204
  })