@tanstack/vue-router 1.146.2 → 1.147.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/HeadContent.js
CHANGED
|
@@ -3,6 +3,23 @@ import { escapeHtml } 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 routeIds = useRouterState({
|
|
10
|
+
select: (state) => state.matches.map((match) => match.routeId)
|
|
11
|
+
});
|
|
12
|
+
Vue.onMounted(() => {
|
|
13
|
+
document.querySelectorAll("[data-tanstack-start-dev-styles]").forEach((el) => el.remove());
|
|
14
|
+
});
|
|
15
|
+
const href = Vue.computed(() => `/@tanstack-start/styles.css?routes=${encodeURIComponent(routeIds.value.join(","))}`);
|
|
16
|
+
return () => Vue.h("link", {
|
|
17
|
+
rel: "stylesheet",
|
|
18
|
+
href: href.value,
|
|
19
|
+
"data-tanstack-start-dev-styles": true
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
6
23
|
const useTags = () => {
|
|
7
24
|
const router = useRouter();
|
|
8
25
|
const routeMeta = useRouterState({
|
|
@@ -104,10 +121,14 @@ const HeadContent = Vue.defineComponent({
|
|
|
104
121
|
setup() {
|
|
105
122
|
const tags = useTags();
|
|
106
123
|
return () => {
|
|
107
|
-
|
|
124
|
+
const children = tags().map((tag) => Vue.h(Asset, {
|
|
108
125
|
...tag,
|
|
109
126
|
key: `tsr-meta-${JSON.stringify(tag)}`
|
|
110
127
|
}));
|
|
128
|
+
if (process.env.NODE_ENV !== "production") {
|
|
129
|
+
return [Vue.h(DevStylesLink), ...children];
|
|
130
|
+
}
|
|
131
|
+
return children;
|
|
111
132
|
};
|
|
112
133
|
}
|
|
113
134
|
});
|
|
@@ -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
|
|
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\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 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 // Build the same href on both server and client for hydration match\n const href = Vue.computed(\n () =>\n `/@tanstack-start/styles.css?routes=${encodeURIComponent(routeIds.value.join(','))}`,\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","routeIds","useRouterState","select","state","matches","map","match","routeId","onMounted","document","querySelectorAll","forEach","el","remove","href","computed","encodeURIComponent","value","join","h","rel","useTags","router","useRouter","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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"}
|
|
@@ -3,6 +3,33 @@ import { 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 routeIds = useRouterState({
|
|
16
|
+
select: (state) => state.matches.map((match) => match.routeId),
|
|
17
|
+
});
|
|
18
|
+
Vue.onMounted(() => {
|
|
19
|
+
// After hydration, remove the SSR-rendered dev styles link
|
|
20
|
+
document
|
|
21
|
+
.querySelectorAll('[data-tanstack-start-dev-styles]')
|
|
22
|
+
.forEach((el) => el.remove());
|
|
23
|
+
});
|
|
24
|
+
// Build the same href on both server and client for hydration match
|
|
25
|
+
const href = Vue.computed(() => `/@tanstack-start/styles.css?routes=${encodeURIComponent(routeIds.value.join(','))}`);
|
|
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
|
-
|
|
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
package/src/HeadContent.tsx
CHANGED
|
@@ -6,6 +6,41 @@ 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 routeIds = useRouterState({
|
|
19
|
+
select: (state) => state.matches.map((match) => match.routeId),
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
Vue.onMounted(() => {
|
|
23
|
+
// After hydration, remove the SSR-rendered dev styles link
|
|
24
|
+
document
|
|
25
|
+
.querySelectorAll('[data-tanstack-start-dev-styles]')
|
|
26
|
+
.forEach((el) => el.remove())
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// Build the same href on both server and client for hydration match
|
|
30
|
+
const href = Vue.computed(
|
|
31
|
+
() =>
|
|
32
|
+
`/@tanstack-start/styles.css?routes=${encodeURIComponent(routeIds.value.join(','))}`,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
return () =>
|
|
36
|
+
Vue.h('link', {
|
|
37
|
+
rel: 'stylesheet',
|
|
38
|
+
href: href.value,
|
|
39
|
+
'data-tanstack-start-dev-styles': true,
|
|
40
|
+
})
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
|
|
9
44
|
export const useTags = () => {
|
|
10
45
|
const router = useRouter()
|
|
11
46
|
|
|
@@ -152,12 +187,19 @@ export const HeadContent = Vue.defineComponent({
|
|
|
152
187
|
const tags = useTags()
|
|
153
188
|
|
|
154
189
|
return () => {
|
|
155
|
-
|
|
190
|
+
const children = tags().map((tag) =>
|
|
156
191
|
Vue.h(Asset, {
|
|
157
192
|
...tag,
|
|
158
193
|
key: `tsr-meta-${JSON.stringify(tag)}`,
|
|
159
194
|
}),
|
|
160
195
|
)
|
|
196
|
+
|
|
197
|
+
// In dev mode, prepend the DevStylesLink
|
|
198
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
199
|
+
return [Vue.h(DevStylesLink), ...children]
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return children
|
|
161
203
|
}
|
|
162
204
|
},
|
|
163
205
|
})
|