From 8ed27971847d9350c72d8e0094264d94711ec2af Mon Sep 17 00:00:00 2001 From: Josh Story Date: Mon, 12 Jun 2023 15:18:38 -0700 Subject: [PATCH] Some browsers, with some CSP configuration, will not preload a script if the prelaod link tag does not provide a valid nonce attribute. This change addes the ability to specify a nonce for `ReactDOM.preload(..., { as: "script" })` --- .../src/client/ReactFiberConfigDOM.js | 1 + .../src/server/ReactFizzConfigDOM.js | 1 + .../src/__tests__/ReactDOMFloat-test.js | 39 +++++++++++++++++++ .../react-dom/src/shared/ReactDOMTypes.js | 1 + 4 files changed, 42 insertions(+) diff --git a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js index 1d70e558f0a27..6e884c0b1f15f 100644 --- a/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js +++ b/packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js @@ -2233,6 +2233,7 @@ function preloadPropsFromPreloadOptions( crossOrigin: as === 'font' ? '' : options.crossOrigin, integrity: options.integrity, type: options.type, + nonce: options.nonce, fetchPriority: options.fetchPriority, }; } diff --git a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js index 0294e57e46ebe..4d23f0ff1afb1 100644 --- a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js +++ b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js @@ -5532,6 +5532,7 @@ function preloadPropsFromPreloadOptions( crossOrigin: as === 'font' ? '' : options.crossOrigin, integrity: options.integrity, type: options.type, + nonce: options.nonce, fetchPriority: options.fetchPriority, }; } diff --git a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js index 92e2f2eef85fa..b73bc3f41e13a 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js @@ -3981,6 +3981,45 @@ body { , ); }); + + it('supports nonce', async () => { + function App({url}) { + ReactDOM.preload(url, {as: 'script', nonce: 'abc'}); + return 'hello'; + } + + await act(() => { + renderToPipeableStream().pipe(writable); + }); + + expect(getMeaningfulChildren(document)).toEqual( + + + +
+ + hello +
+ + , + ); + + ReactDOMClient.hydrateRoot(container, ); + await waitForAll([]); + expect(getMeaningfulChildren(document)).toEqual( + + + + + +
+ + hello +
+ + , + ); + }); }); describe('ReactDOM.preinit(href, { as: ... })', () => { diff --git a/packages/react-dom/src/shared/ReactDOMTypes.js b/packages/react-dom/src/shared/ReactDOMTypes.js index 2bd42537400a0..61d220bf11b52 100644 --- a/packages/react-dom/src/shared/ReactDOMTypes.js +++ b/packages/react-dom/src/shared/ReactDOMTypes.js @@ -14,6 +14,7 @@ export type PreloadOptions = { crossOrigin?: string, integrity?: string, type?: string, + nonce?: string, fetchPriority?: 'high' | 'low' | 'auto', }; export type PreinitOptions = {