diff --git a/packages/react-router/src/Asset.tsx b/packages/react-router/src/Asset.tsx
index c16c65ad45e..37347631cf4 100644
--- a/packages/react-router/src/Asset.tsx
+++ b/packages/react-router/src/Asset.tsx
@@ -34,11 +34,7 @@ export function Asset({
/>
)
case 'script':
- return (
-
- )
+ return
default:
return null
}
@@ -47,11 +43,9 @@ export function Asset({
function Script({
attrs,
children,
- nonce,
}: {
attrs?: ScriptAttrs
children?: string
- nonce?: string
}) {
const router = useRouter()
@@ -154,7 +148,7 @@ function Script({
}
if (attrs?.src && typeof attrs.src === 'string') {
- return
+ return
}
if (typeof children === 'string') {
@@ -163,7 +157,6 @@ function Script({
{...attrs}
dangerouslySetInnerHTML={{ __html: children }}
suppressHydrationWarning
- nonce={nonce}
/>
)
}
diff --git a/packages/react-router/src/HeadContent.tsx b/packages/react-router/src/HeadContent.tsx
index 690e046bd7e..c3ac2bbafea 100644
--- a/packages/react-router/src/HeadContent.tsx
+++ b/packages/react-router/src/HeadContent.tsx
@@ -6,7 +6,7 @@ import type { RouterManagedTag } from '@tanstack/router-core'
export const useTags = () => {
const router = useRouter()
-
+ const nonce = router.options.ssr?.nonce
const routeMeta = useRouterState({
select: (state) => {
return state.matches.map((match) => match.meta!).filter(Boolean)
@@ -44,6 +44,7 @@ export const useTags = () => {
tag: 'meta',
attrs: {
...m,
+ nonce,
},
})
}
@@ -54,6 +55,15 @@ export const useTags = () => {
resultMeta.push(title)
}
+ if (router.options.ssr?.nonce) {
+ resultMeta.push({
+ tag: 'meta',
+ attrs: {
+ property: 'csp-nonce',
+ content: router.options.ssr.nonce,
+ },
+ })
+ }
resultMeta.reverse()
return resultMeta
@@ -69,6 +79,7 @@ export const useTags = () => {
tag: 'link',
attrs: {
...link,
+ nonce,
},
})) satisfies Array
@@ -88,6 +99,7 @@ export const useTags = () => {
attrs: {
...asset.attrs,
suppressHydrationWarning: true,
+ nonce,
},
}) satisfies RouterManagedTag,
)
@@ -112,6 +124,7 @@ export const useTags = () => {
attrs: {
rel: 'modulepreload',
href: preload,
+ nonce,
},
})
}),
@@ -133,6 +146,7 @@ export const useTags = () => {
tag: 'style',
attrs,
children,
+ nonce,
})),
structuralSharing: true as any,
})
@@ -148,6 +162,7 @@ export const useTags = () => {
tag: 'script',
attrs: {
...script,
+ nonce,
},
children,
})),
diff --git a/packages/react-router/src/Scripts.tsx b/packages/react-router/src/Scripts.tsx
index beb332cbd72..28c05bf2749 100644
--- a/packages/react-router/src/Scripts.tsx
+++ b/packages/react-router/src/Scripts.tsx
@@ -5,7 +5,7 @@ import type { RouterManagedTag } from '@tanstack/router-core'
export const Scripts = () => {
const router = useRouter()
-
+ const nonce = router.options.ssr?.nonce
const assetScripts = useRouterState({
select: (state) => {
const assetScripts: Array = []
@@ -23,7 +23,7 @@ export const Scripts = () => {
.forEach((asset) => {
assetScripts.push({
tag: 'script',
- attrs: asset.attrs,
+ attrs: { ...asset.attrs, nonce },
children: asset.children,
} as any)
}),
@@ -46,6 +46,7 @@ export const Scripts = () => {
attrs: {
...script,
suppressHydrationWarning: true,
+ nonce,
},
children,
})),
@@ -58,11 +59,7 @@ export const Scripts = () => {
return (
<>
{allScripts.map((asset, i) => (
-
+
))}
>
)
diff --git a/packages/router-core/src/ssr/ssr-client.ts b/packages/router-core/src/ssr/ssr-client.ts
index cff2dc61bee..736fbeac6ca 100644
--- a/packages/router-core/src/ssr/ssr-client.ts
+++ b/packages/router-core/src/ssr/ssr-client.ts
@@ -86,6 +86,13 @@ export async function hydrate(router: AnyRouter): Promise {
router.ssr = {
manifest,
}
+ const meta = document.querySelector('meta[property="csp-nonce"]') as
+ | HTMLMetaElement
+ | undefined
+ const nonce = meta?.content
+ router.options.ssr = {
+ nonce,
+ }
// Hydrate the router state
const matches = router.matchRoutes(router.state.location)
diff --git a/packages/solid-router/src/HeadContent.tsx b/packages/solid-router/src/HeadContent.tsx
index 820473e3b31..0292b52d120 100644
--- a/packages/solid-router/src/HeadContent.tsx
+++ b/packages/solid-router/src/HeadContent.tsx
@@ -7,7 +7,7 @@ import type { RouterManagedTag } from '@tanstack/router-core'
export const useTags = () => {
const router = useRouter()
-
+ const nonce = router.options.ssr?.nonce
const routeMeta = useRouterState({
select: (state) => {
return state.matches.map((match) => match.meta!).filter(Boolean)
@@ -46,6 +46,7 @@ export const useTags = () => {
tag: 'meta',
attrs: {
...m,
+ nonce,
},
})
}
@@ -56,6 +57,15 @@ export const useTags = () => {
resultMeta.push(title)
}
+ if (router.options.ssr?.nonce) {
+ resultMeta.push({
+ tag: 'meta',
+ attrs: {
+ property: 'csp-nonce',
+ content: router.options.ssr.nonce,
+ },
+ })
+ }
resultMeta.reverse()
return resultMeta
@@ -71,6 +81,7 @@ export const useTags = () => {
tag: 'link',
attrs: {
...link,
+ nonce,
},
})) satisfies Array
@@ -87,7 +98,7 @@ export const useTags = () => {
(asset) =>
({
tag: 'link',
- attrs: asset.attrs,
+ attrs: { ...asset.attrs, nonce },
}) satisfies RouterManagedTag,
)
@@ -110,6 +121,7 @@ export const useTags = () => {
attrs: {
rel: 'modulepreload',
href: preload,
+ nonce,
},
})
}),
@@ -130,6 +142,7 @@ export const useTags = () => {
tag: 'style',
attrs: {
...style,
+ nonce,
},
children,
})),
@@ -146,6 +159,7 @@ export const useTags = () => {
tag: 'script',
attrs: {
...script,
+ nonce,
},
children,
})),
@@ -172,6 +186,7 @@ export const useTags = () => {
*/
export function HeadContent() {
const tags = useTags()
+
return (
{tags().map((tag) => (
diff --git a/packages/solid-router/src/Scripts.tsx b/packages/solid-router/src/Scripts.tsx
index e3fdca99a43..798ae1adf37 100644
--- a/packages/solid-router/src/Scripts.tsx
+++ b/packages/solid-router/src/Scripts.tsx
@@ -5,7 +5,7 @@ import type { RouterManagedTag } from '@tanstack/router-core'
export const Scripts = () => {
const router = useRouter()
-
+ const nonce = router.options.ssr?.nonce
const assetScripts = useRouterState({
select: (state) => {
const assetScripts: Array = []
@@ -23,7 +23,7 @@ export const Scripts = () => {
.forEach((asset) => {
assetScripts.push({
tag: 'script',
- attrs: asset.attrs,
+ attrs: { ...asset.attrs, nonce },
children: asset.children,
} as any)
}),
@@ -44,6 +44,7 @@ export const Scripts = () => {
tag: 'script',
attrs: {
...script,
+ nonce,
},
children,
})),