@@ -8,10 +8,13 @@ import { getScriptToRunAsap } from "../useIsDark/scriptToRunAsap";
88import { fontUrlByFileBasename } from "./zz_internal/fontUrlByFileBasename" ;
99import { getDefaultColorSchemeServerSide } from "./zz_internal/defaultColorScheme" ;
1010import { setLink , type RegisteredLinkProps } from "../link" ;
11+ import { assert } from "tsafe/assert" ;
1112//NOTE: As of now there is no way to enforce ordering in Next Appdir
1213//See: https://github.com/vercel/next.js/issues/16630
1314// @import url(...) doesn't work. Using Sass and @use is our last resort.
1415import "../assets/dsfr_plus_icons.scss" ;
16+ // eslint-disable-next-line @typescript-eslint/no-unused-vars -- used in doc
17+ import { type startReactDsfr } from "./zz_internal/start" ;
1518
1619export type DsfrHeadProps = {
1720 /** If not provided no fonts are preloaded.
@@ -20,12 +23,32 @@ export type DsfrHeadProps = {
2023 preloadFonts ?: ( keyof typeof fontUrlByFileBasename ) [ ] ;
2124 /** Default: <a /> */
2225 Link ?: ( props : RegisteredLinkProps & { children : ReactNode } ) => ReturnType < React . FC > ;
26+ /**
27+ * When set, the value will be used as the nonce attribute of subsequent script tags.
28+ *
29+ * Don't forget to add `doCheckNonce: true` in {@link startReactDsfr} options.
30+ *
31+ * @see https://developer.mozilla.org/fr/docs/Web/HTML/Global_attributes/nonce
32+ */
33+ nonce ?: string ;
34+ /**
35+ * Enable Trusted Types with a custom policy name.
36+ *
37+ * Don't forget to add `trustedTypesPolicyName` in {@link startReactDsfr} options.
38+ *
39+ * @see https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Content-Security-Policy/trusted-types
40+ * @see {@link DEFAULT_TRUSTED_TYPES_POLICY_NAME }
41+ * @default "react-dsfr"
42+ */
43+ trustedTypesPolicyName ?: string ;
2344} ;
2445
2546const isProduction = process . env . NODE_ENV !== "development" ;
2647
2748export function DsfrHead ( props : DsfrHeadProps ) {
28- const { preloadFonts = [ ] , Link } = props ;
49+ const { preloadFonts = [ ] , Link, nonce, trustedTypesPolicyName = "react-dsfr" } = props ;
50+
51+ assert ( nonce !== "" , "nonce cannot be an empty string" ) ;
2952
3053 const defaultColorScheme = getDefaultColorSchemeServerSide ( ) ;
3154
@@ -53,9 +76,25 @@ export function DsfrHead(props: DsfrHeadProps) {
5376 < link rel = "apple-touch-icon" href = { getAssetUrl ( AppleTouchIcon ) } />
5477 < link rel = "icon" href = { getAssetUrl ( FaviconSvg ) } type = "image/svg+xml" />
5578 < link rel = "shortcut icon" href = { getAssetUrl ( FaviconIco ) } type = "image/x-icon" />
56- { isProduction && (
79+ < script
80+ suppressHydrationWarning
81+ nonce = { nonce }
82+ dangerouslySetInnerHTML = { {
83+ "__html" : getScriptToRunAsap ( {
84+ defaultColorScheme,
85+ nonce,
86+ trustedTypesPolicyName
87+ } )
88+ } }
89+ />
90+ { nonce !== undefined && (
5791 < script
58- dangerouslySetInnerHTML = { { "__html" : getScriptToRunAsap ( defaultColorScheme ) } }
92+ suppressHydrationWarning
93+ key = "nonce-setter"
94+ nonce = { nonce }
95+ dangerouslySetInnerHTML = { {
96+ __html : `window.ssrNonce = "${ nonce } ";`
97+ } }
5998 />
6099 ) }
61100 </ >
0 commit comments