@tanstack/react-router 1.147.2 → 1.147.3
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/cjs/HeadContent.cjs +3 -201
- package/dist/cjs/HeadContent.cjs.map +1 -1
- package/dist/cjs/HeadContent.d.cts +0 -6
- package/dist/cjs/HeadContent.dev.cjs +41 -0
- package/dist/cjs/HeadContent.dev.cjs.map +1 -0
- package/dist/cjs/HeadContent.dev.d.cts +10 -0
- package/dist/cjs/headContentUtils.cjs +185 -0
- package/dist/cjs/headContentUtils.cjs.map +1 -0
- package/dist/cjs/headContentUtils.d.cts +7 -0
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -0
- package/dist/cjs/index.dev.cjs +264 -0
- package/dist/cjs/index.dev.cjs.map +1 -0
- package/dist/cjs/index.dev.d.cts +2 -0
- package/dist/esm/HeadContent.d.ts +0 -6
- package/dist/esm/HeadContent.dev.d.ts +10 -0
- package/dist/esm/HeadContent.dev.js +25 -0
- package/dist/esm/HeadContent.dev.js.map +1 -0
- package/dist/esm/HeadContent.js +4 -186
- package/dist/esm/HeadContent.js.map +1 -1
- package/dist/esm/headContentUtils.d.ts +7 -0
- package/dist/esm/headContentUtils.js +168 -0
- package/dist/esm/headContentUtils.js.map +1 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.dev.d.ts +2 -0
- package/dist/esm/index.dev.js +144 -0
- package/dist/esm/index.dev.js.map +1 -0
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/package.json +5 -3
- package/src/HeadContent.dev.tsx +46 -0
- package/src/HeadContent.tsx +1 -245
- package/src/headContentUtils.tsx +217 -0
- package/src/index.dev.tsx +6 -0
- package/src/index.tsx +1 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { escapeHtml } from "@tanstack/router-core";
|
|
3
|
+
import { useRouter } from "./useRouter.js";
|
|
4
|
+
import { useRouterState } from "./useRouterState.js";
|
|
5
|
+
const useTags = () => {
|
|
6
|
+
const router = useRouter();
|
|
7
|
+
const nonce = router.options.ssr?.nonce;
|
|
8
|
+
const routeMeta = useRouterState({
|
|
9
|
+
select: (state) => {
|
|
10
|
+
return state.matches.map((match) => match.meta).filter(Boolean);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
const meta = React.useMemo(() => {
|
|
14
|
+
const resultMeta = [];
|
|
15
|
+
const metaByAttribute = {};
|
|
16
|
+
let title;
|
|
17
|
+
for (let i = routeMeta.length - 1; i >= 0; i--) {
|
|
18
|
+
const metas = routeMeta[i];
|
|
19
|
+
for (let j = metas.length - 1; j >= 0; j--) {
|
|
20
|
+
const m = metas[j];
|
|
21
|
+
if (!m) continue;
|
|
22
|
+
if (m.title) {
|
|
23
|
+
if (!title) {
|
|
24
|
+
title = {
|
|
25
|
+
tag: "title",
|
|
26
|
+
children: m.title
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
} else if ("script:ld+json" in m) {
|
|
30
|
+
try {
|
|
31
|
+
const json = JSON.stringify(m["script:ld+json"]);
|
|
32
|
+
resultMeta.push({
|
|
33
|
+
tag: "script",
|
|
34
|
+
attrs: {
|
|
35
|
+
type: "application/ld+json"
|
|
36
|
+
},
|
|
37
|
+
children: escapeHtml(json)
|
|
38
|
+
});
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
const attribute = m.name ?? m.property;
|
|
43
|
+
if (attribute) {
|
|
44
|
+
if (metaByAttribute[attribute]) {
|
|
45
|
+
continue;
|
|
46
|
+
} else {
|
|
47
|
+
metaByAttribute[attribute] = true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
resultMeta.push({
|
|
51
|
+
tag: "meta",
|
|
52
|
+
attrs: {
|
|
53
|
+
...m,
|
|
54
|
+
nonce
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (title) {
|
|
61
|
+
resultMeta.push(title);
|
|
62
|
+
}
|
|
63
|
+
if (nonce) {
|
|
64
|
+
resultMeta.push({
|
|
65
|
+
tag: "meta",
|
|
66
|
+
attrs: {
|
|
67
|
+
property: "csp-nonce",
|
|
68
|
+
content: nonce
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
resultMeta.reverse();
|
|
73
|
+
return resultMeta;
|
|
74
|
+
}, [routeMeta, nonce]);
|
|
75
|
+
const links = useRouterState({
|
|
76
|
+
select: (state) => {
|
|
77
|
+
const constructed = state.matches.map((match) => match.links).filter(Boolean).flat(1).map((link) => ({
|
|
78
|
+
tag: "link",
|
|
79
|
+
attrs: {
|
|
80
|
+
...link,
|
|
81
|
+
nonce
|
|
82
|
+
}
|
|
83
|
+
}));
|
|
84
|
+
const manifest = router.ssr?.manifest;
|
|
85
|
+
const assets = state.matches.map((match) => manifest?.routes[match.routeId]?.assets ?? []).filter(Boolean).flat(1).filter((asset) => asset.tag === "link").map(
|
|
86
|
+
(asset) => ({
|
|
87
|
+
tag: "link",
|
|
88
|
+
attrs: {
|
|
89
|
+
...asset.attrs,
|
|
90
|
+
suppressHydrationWarning: true,
|
|
91
|
+
nonce
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
);
|
|
95
|
+
return [...constructed, ...assets];
|
|
96
|
+
},
|
|
97
|
+
structuralSharing: true
|
|
98
|
+
});
|
|
99
|
+
const preloadLinks = useRouterState({
|
|
100
|
+
select: (state) => {
|
|
101
|
+
const preloadLinks2 = [];
|
|
102
|
+
state.matches.map((match) => router.looseRoutesById[match.routeId]).forEach(
|
|
103
|
+
(route) => router.ssr?.manifest?.routes[route.id]?.preloads?.filter(Boolean).forEach((preload) => {
|
|
104
|
+
preloadLinks2.push({
|
|
105
|
+
tag: "link",
|
|
106
|
+
attrs: {
|
|
107
|
+
rel: "modulepreload",
|
|
108
|
+
href: preload,
|
|
109
|
+
nonce
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
})
|
|
113
|
+
);
|
|
114
|
+
return preloadLinks2;
|
|
115
|
+
},
|
|
116
|
+
structuralSharing: true
|
|
117
|
+
});
|
|
118
|
+
const styles = useRouterState({
|
|
119
|
+
select: (state) => state.matches.map((match) => match.styles).flat(1).filter(Boolean).map(({ children, ...attrs }) => ({
|
|
120
|
+
tag: "style",
|
|
121
|
+
attrs: {
|
|
122
|
+
...attrs,
|
|
123
|
+
nonce
|
|
124
|
+
},
|
|
125
|
+
children
|
|
126
|
+
})),
|
|
127
|
+
structuralSharing: true
|
|
128
|
+
});
|
|
129
|
+
const headScripts = useRouterState({
|
|
130
|
+
select: (state) => state.matches.map((match) => match.headScripts).flat(1).filter(Boolean).map(({ children, ...script }) => ({
|
|
131
|
+
tag: "script",
|
|
132
|
+
attrs: {
|
|
133
|
+
...script,
|
|
134
|
+
nonce
|
|
135
|
+
},
|
|
136
|
+
children
|
|
137
|
+
})),
|
|
138
|
+
structuralSharing: true
|
|
139
|
+
});
|
|
140
|
+
return uniqBy(
|
|
141
|
+
[
|
|
142
|
+
...meta,
|
|
143
|
+
...preloadLinks,
|
|
144
|
+
...links,
|
|
145
|
+
...styles,
|
|
146
|
+
...headScripts
|
|
147
|
+
],
|
|
148
|
+
(d) => {
|
|
149
|
+
return JSON.stringify(d);
|
|
150
|
+
}
|
|
151
|
+
);
|
|
152
|
+
};
|
|
153
|
+
function uniqBy(arr, fn) {
|
|
154
|
+
const seen = /* @__PURE__ */ new Set();
|
|
155
|
+
return arr.filter((item) => {
|
|
156
|
+
const key = fn(item);
|
|
157
|
+
if (seen.has(key)) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
seen.add(key);
|
|
161
|
+
return true;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
export {
|
|
165
|
+
uniqBy,
|
|
166
|
+
useTags
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=headContentUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headContentUtils.js","sources":["../../src/headContentUtils.tsx"],"sourcesContent":["import * as React from 'react'\nimport { escapeHtml } from '@tanstack/router-core'\nimport { useRouter } from './useRouter'\nimport { useRouterState } from './useRouterState'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\n/**\n * Build the list of head/link/meta/script tags to render for active matches.\n * Used internally by `HeadContent`.\n */\nexport const useTags = () => {\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n const routeMeta = useRouterState({\n select: (state) => {\n return state.matches.map((match) => match.meta!).filter(Boolean)\n },\n })\n\n const meta: Array<RouterManagedTag> = React.useMemo(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n for (let i = routeMeta.length - 1; i >= 0; i--) {\n const metas = routeMeta[i]!\n for (let j = metas.length - 1; j >= 0; j--) {\n const m = metas[j]\n if (!m) continue\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 dangerouslySetInnerHTML\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 continue\n } else {\n metaByAttribute[attribute] = true\n }\n }\n\n resultMeta.push({\n tag: 'meta',\n attrs: {\n ...m,\n nonce,\n },\n })\n }\n }\n }\n\n if (title) {\n resultMeta.push(title)\n }\n\n if (nonce) {\n resultMeta.push({\n tag: 'meta',\n attrs: {\n property: 'csp-nonce',\n content: nonce,\n },\n })\n }\n resultMeta.reverse()\n\n return resultMeta\n }, [routeMeta, nonce])\n\n const links = useRouterState({\n select: (state) => {\n const constructed = state.matches\n .map((match) => match.links!)\n .filter(Boolean)\n .flat(1)\n .map((link) => ({\n tag: 'link',\n attrs: {\n ...link,\n nonce,\n },\n })) satisfies Array<RouterManagedTag>\n\n const manifest = router.ssr?.manifest\n\n // These are the assets extracted from the ViteManifest\n // using the `startManifestPlugin`\n const assets = state.matches\n .map((match) => manifest?.routes[match.routeId]?.assets ?? [])\n .filter(Boolean)\n .flat(1)\n .filter((asset) => asset.tag === 'link')\n .map(\n (asset) =>\n ({\n tag: 'link',\n attrs: {\n ...asset.attrs,\n suppressHydrationWarning: true,\n nonce,\n },\n }) satisfies RouterManagedTag,\n )\n\n return [...constructed, ...assets]\n },\n structuralSharing: true as any,\n })\n\n const preloadLinks = useRouterState({\n select: (state) => {\n const preloadLinks: 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 preloadLinks.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n nonce,\n },\n })\n }),\n )\n\n return preloadLinks\n },\n structuralSharing: true as any,\n })\n\n const styles = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.styles!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...attrs }) => ({\n tag: 'style',\n attrs: {\n ...attrs,\n nonce,\n },\n children,\n })),\n structuralSharing: true as any,\n })\n\n const headScripts: Array<RouterManagedTag> = 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 nonce,\n },\n children,\n })),\n structuralSharing: true as any,\n })\n\n return uniqBy(\n [\n ...meta,\n ...preloadLinks,\n ...links,\n ...styles,\n ...headScripts,\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"],"names":["preloadLinks"],"mappings":"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"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ export type { ValidateFromPath, ValidateToPath, ValidateSearch, ValidateParams,
|
|
|
48
48
|
export { ScriptOnce } from './ScriptOnce.js';
|
|
49
49
|
export { Asset } from './Asset.js';
|
|
50
50
|
export { HeadContent } from './HeadContent.js';
|
|
51
|
+
export { useTags } from './headContentUtils.js';
|
|
51
52
|
export { Scripts } from './Scripts.js';
|
|
52
53
|
export type * from './ssr/serializer.js';
|
|
53
54
|
export { composeRewrites } from '@tanstack/router-core';
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { PathParamError, SearchParamError, TSR_DEFERRED_PROMISE, cleanPath, componentTypes, composeRewrites, createControlledPromise, createRouterConfig, createSerializationAdapter, deepEqual, defaultParseSearch, defaultSerializeError, defaultStringifySearch, defer, functionalUpdate, getInitialRouterState, interpolatePath, isMatch, isNotFound, isPlainArray, isPlainObject, isRedirect, joinPaths, lazyFn, notFound, parseSearchWith, redirect, replaceEqualDeep, resolvePath, retainSearchParams, rootRouteId, stringifySearchWith, stripSearchParams, trimPath, trimPathLeft, trimPathRight } from "@tanstack/router-core";
|
|
2
|
+
import { createBrowserHistory, createHashHistory, createHistory, createMemoryHistory } from "@tanstack/history";
|
|
3
|
+
import { Await, useAwaited } from "./awaited.js";
|
|
4
|
+
import { CatchBoundary, ErrorComponent } from "./CatchBoundary.js";
|
|
5
|
+
import { ClientOnly, useHydrated } from "./ClientOnly.js";
|
|
6
|
+
import { FileRoute, FileRouteLoader, LazyRoute, createFileRoute, createLazyFileRoute, createLazyRoute } from "./fileRoute.js";
|
|
7
|
+
import { lazyRouteComponent } from "./lazyRouteComponent.js";
|
|
8
|
+
import { Link, createLink, linkOptions, useLinkProps } from "./link.js";
|
|
9
|
+
import { MatchRoute, Matches, useChildMatches, useMatchRoute, useMatches, useParentMatches } from "./Matches.js";
|
|
10
|
+
import { matchContext } from "./matchContext.js";
|
|
11
|
+
import { Match, Outlet } from "./Match.js";
|
|
12
|
+
import { useMatch } from "./useMatch.js";
|
|
13
|
+
import { useLoaderDeps } from "./useLoaderDeps.js";
|
|
14
|
+
import { useLoaderData } from "./useLoaderData.js";
|
|
15
|
+
import { NotFoundRoute, RootRoute, Route, RouteApi, createRootRoute, createRootRouteWithContext, createRoute, createRouteMask, getRouteApi, rootRouteWithContext } from "./route.js";
|
|
16
|
+
import { Router, createRouter } from "./router.js";
|
|
17
|
+
import { RouterContextProvider, RouterProvider } from "./RouterProvider.js";
|
|
18
|
+
import { ScrollRestoration, useElementScrollRestoration } from "./ScrollRestoration.js";
|
|
19
|
+
import { Block, useBlocker } from "./useBlocker.js";
|
|
20
|
+
import { Navigate, useNavigate } from "./useNavigate.js";
|
|
21
|
+
import { useParams } from "./useParams.js";
|
|
22
|
+
import { useSearch } from "./useSearch.js";
|
|
23
|
+
import { getRouterContext } from "./routerContext.js";
|
|
24
|
+
import { useRouteContext } from "./useRouteContext.js";
|
|
25
|
+
import { useRouter } from "./useRouter.js";
|
|
26
|
+
import { useRouterState } from "./useRouterState.js";
|
|
27
|
+
import { useLocation } from "./useLocation.js";
|
|
28
|
+
import { useCanGoBack } from "./useCanGoBack.js";
|
|
29
|
+
import { useLayoutEffect, useStableCallback } from "./utils.js";
|
|
30
|
+
import { CatchNotFound, DefaultGlobalNotFound } from "./not-found.js";
|
|
31
|
+
import { ScriptOnce } from "./ScriptOnce.js";
|
|
32
|
+
import { Asset } from "./Asset.js";
|
|
33
|
+
import { useTags } from "./headContentUtils.js";
|
|
34
|
+
import { Scripts } from "./Scripts.js";
|
|
35
|
+
import { HeadContent } from "./HeadContent.dev.js";
|
|
36
|
+
export {
|
|
37
|
+
Asset,
|
|
38
|
+
Await,
|
|
39
|
+
Block,
|
|
40
|
+
CatchBoundary,
|
|
41
|
+
CatchNotFound,
|
|
42
|
+
ClientOnly,
|
|
43
|
+
DefaultGlobalNotFound,
|
|
44
|
+
ErrorComponent,
|
|
45
|
+
FileRoute,
|
|
46
|
+
FileRouteLoader,
|
|
47
|
+
HeadContent,
|
|
48
|
+
LazyRoute,
|
|
49
|
+
Link,
|
|
50
|
+
Match,
|
|
51
|
+
MatchRoute,
|
|
52
|
+
Matches,
|
|
53
|
+
Navigate,
|
|
54
|
+
NotFoundRoute,
|
|
55
|
+
Outlet,
|
|
56
|
+
PathParamError,
|
|
57
|
+
RootRoute,
|
|
58
|
+
Route,
|
|
59
|
+
RouteApi,
|
|
60
|
+
Router,
|
|
61
|
+
RouterContextProvider,
|
|
62
|
+
RouterProvider,
|
|
63
|
+
ScriptOnce,
|
|
64
|
+
Scripts,
|
|
65
|
+
ScrollRestoration,
|
|
66
|
+
SearchParamError,
|
|
67
|
+
TSR_DEFERRED_PROMISE,
|
|
68
|
+
cleanPath,
|
|
69
|
+
componentTypes,
|
|
70
|
+
composeRewrites,
|
|
71
|
+
createBrowserHistory,
|
|
72
|
+
createControlledPromise,
|
|
73
|
+
createFileRoute,
|
|
74
|
+
createHashHistory,
|
|
75
|
+
createHistory,
|
|
76
|
+
createLazyFileRoute,
|
|
77
|
+
createLazyRoute,
|
|
78
|
+
createLink,
|
|
79
|
+
createMemoryHistory,
|
|
80
|
+
createRootRoute,
|
|
81
|
+
createRootRouteWithContext,
|
|
82
|
+
createRoute,
|
|
83
|
+
createRouteMask,
|
|
84
|
+
createRouter,
|
|
85
|
+
createRouterConfig,
|
|
86
|
+
createSerializationAdapter,
|
|
87
|
+
deepEqual,
|
|
88
|
+
defaultParseSearch,
|
|
89
|
+
defaultSerializeError,
|
|
90
|
+
defaultStringifySearch,
|
|
91
|
+
defer,
|
|
92
|
+
functionalUpdate,
|
|
93
|
+
getInitialRouterState,
|
|
94
|
+
getRouteApi,
|
|
95
|
+
getRouterContext,
|
|
96
|
+
interpolatePath,
|
|
97
|
+
isMatch,
|
|
98
|
+
isNotFound,
|
|
99
|
+
isPlainArray,
|
|
100
|
+
isPlainObject,
|
|
101
|
+
isRedirect,
|
|
102
|
+
joinPaths,
|
|
103
|
+
lazyFn,
|
|
104
|
+
lazyRouteComponent,
|
|
105
|
+
linkOptions,
|
|
106
|
+
matchContext,
|
|
107
|
+
notFound,
|
|
108
|
+
parseSearchWith,
|
|
109
|
+
redirect,
|
|
110
|
+
replaceEqualDeep,
|
|
111
|
+
resolvePath,
|
|
112
|
+
retainSearchParams,
|
|
113
|
+
rootRouteId,
|
|
114
|
+
rootRouteWithContext,
|
|
115
|
+
stringifySearchWith,
|
|
116
|
+
stripSearchParams,
|
|
117
|
+
trimPath,
|
|
118
|
+
trimPathLeft,
|
|
119
|
+
trimPathRight,
|
|
120
|
+
useAwaited,
|
|
121
|
+
useBlocker,
|
|
122
|
+
useCanGoBack,
|
|
123
|
+
useChildMatches,
|
|
124
|
+
useElementScrollRestoration,
|
|
125
|
+
useHydrated,
|
|
126
|
+
useLayoutEffect,
|
|
127
|
+
useLinkProps,
|
|
128
|
+
useLoaderData,
|
|
129
|
+
useLoaderDeps,
|
|
130
|
+
useLocation,
|
|
131
|
+
useMatch,
|
|
132
|
+
useMatchRoute,
|
|
133
|
+
useMatches,
|
|
134
|
+
useNavigate,
|
|
135
|
+
useParams,
|
|
136
|
+
useParentMatches,
|
|
137
|
+
useRouteContext,
|
|
138
|
+
useRouter,
|
|
139
|
+
useRouterState,
|
|
140
|
+
useSearch,
|
|
141
|
+
useStableCallback,
|
|
142
|
+
useTags
|
|
143
|
+
};
|
|
144
|
+
//# sourceMappingURL=index.dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.dev.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/esm/index.js
CHANGED
|
@@ -31,6 +31,7 @@ import { CatchNotFound, DefaultGlobalNotFound } from "./not-found.js";
|
|
|
31
31
|
import { ScriptOnce } from "./ScriptOnce.js";
|
|
32
32
|
import { Asset } from "./Asset.js";
|
|
33
33
|
import { HeadContent } from "./HeadContent.js";
|
|
34
|
+
import { useTags } from "./headContentUtils.js";
|
|
34
35
|
import { Scripts } from "./Scripts.js";
|
|
35
36
|
export {
|
|
36
37
|
Asset,
|
|
@@ -137,6 +138,7 @@ export {
|
|
|
137
138
|
useRouter,
|
|
138
139
|
useRouterState,
|
|
139
140
|
useSearch,
|
|
140
|
-
useStableCallback
|
|
141
|
+
useStableCallback,
|
|
142
|
+
useTags
|
|
141
143
|
};
|
|
142
144
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/react-router",
|
|
3
|
-
"version": "1.147.
|
|
3
|
+
"version": "1.147.3",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,10 +31,12 @@
|
|
|
31
31
|
".": {
|
|
32
32
|
"import": {
|
|
33
33
|
"types": "./dist/esm/index.d.ts",
|
|
34
|
+
"development": "./dist/esm/index.dev.js",
|
|
34
35
|
"default": "./dist/esm/index.js"
|
|
35
36
|
},
|
|
36
37
|
"require": {
|
|
37
38
|
"types": "./dist/cjs/index.d.cts",
|
|
39
|
+
"development": "./dist/cjs/index.dev.cjs",
|
|
38
40
|
"default": "./dist/cjs/index.cjs"
|
|
39
41
|
}
|
|
40
42
|
},
|
|
@@ -79,8 +81,8 @@
|
|
|
79
81
|
"isbot": "^5.1.22",
|
|
80
82
|
"tiny-invariant": "^1.3.3",
|
|
81
83
|
"tiny-warning": "^1.0.3",
|
|
82
|
-
"@tanstack/
|
|
83
|
-
"@tanstack/
|
|
84
|
+
"@tanstack/history": "1.145.7",
|
|
85
|
+
"@tanstack/router-core": "1.147.1"
|
|
84
86
|
},
|
|
85
87
|
"devDependencies": {
|
|
86
88
|
"@testing-library/jest-dom": "^6.6.3",
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import { Asset } from './Asset'
|
|
3
|
+
import { useRouter } from './useRouter'
|
|
4
|
+
import { useHydrated } from './ClientOnly'
|
|
5
|
+
import { useTags } from './headContentUtils'
|
|
6
|
+
|
|
7
|
+
const DEV_STYLES_ATTR = 'data-tanstack-router-dev-styles'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Render route-managed head tags (title, meta, links, styles, head scripts).
|
|
11
|
+
* Place inside the document head of your app shell.
|
|
12
|
+
*
|
|
13
|
+
* Development version: filters out dev styles link after hydration and
|
|
14
|
+
* includes a fallback cleanup effect for hydration mismatch cases.
|
|
15
|
+
*
|
|
16
|
+
* @link https://tanstack.com/router/latest/docs/framework/react/guide/document-head-management
|
|
17
|
+
*/
|
|
18
|
+
export function HeadContent() {
|
|
19
|
+
const tags = useTags()
|
|
20
|
+
const router = useRouter()
|
|
21
|
+
const nonce = router.options.ssr?.nonce
|
|
22
|
+
const hydrated = useHydrated()
|
|
23
|
+
|
|
24
|
+
// Fallback cleanup for hydration mismatch cases
|
|
25
|
+
// Runs when hydration completes to remove any orphaned dev styles links from DOM
|
|
26
|
+
React.useEffect(() => {
|
|
27
|
+
if (hydrated) {
|
|
28
|
+
document
|
|
29
|
+
.querySelectorAll(`link[${DEV_STYLES_ATTR}]`)
|
|
30
|
+
.forEach((el) => el.remove())
|
|
31
|
+
}
|
|
32
|
+
}, [hydrated])
|
|
33
|
+
|
|
34
|
+
// Filter out dev styles after hydration
|
|
35
|
+
const filteredTags = hydrated
|
|
36
|
+
? tags.filter((tag) => !tag.attrs?.[DEV_STYLES_ATTR])
|
|
37
|
+
: tags
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<>
|
|
41
|
+
{filteredTags.map((tag) => (
|
|
42
|
+
<Asset {...tag} key={`tsr-meta-${JSON.stringify(tag)}`} nonce={nonce} />
|
|
43
|
+
))}
|
|
44
|
+
</>
|
|
45
|
+
)
|
|
46
|
+
}
|