Update preload links to support nonce and fetchpriority (#26826)
Currently when React generates rel=preload link tags for script/stylesheet resources, it will not carryover nonce and fetchpriority values if specified on the original elements. This change ensures that the preload links use the nonce and fetchPriority values if they were specified.
Yen-Wei Liu committed
May 22, 2023 at 19:56 UTC
535c038d15d21f33e678187410d658456cc0ce39
2 files changed
+79
packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
+3
@@ -5510,6 +5510,7 @@ function preloadAsStylePropsFromProps(href: string, props: any): PreloadProps {
5510
as: 'style',
5511
href: href,
5512
crossOrigin: props.crossOrigin,
5513
+ fetchPriority: props.fetchPriority,
5514
integrity: props.integrity,
5515
media: props.media,
5516
hrefLang: props.hrefLang,
@@ -5523,7 +5524,9 @@ function preloadAsScriptPropsFromProps(href: string, props: any): PreloadProps {
5524
as: 'script',
5525
href,
5526
crossOrigin: props.crossOrigin,
5527
+ fetchPriority: props.fetchPriority,
5528
integrity: props.integrity,
5529
+ nonce: props.nonce,
5530
referrerPolicy: props.referrerPolicy,
5531
};
5532
}
packages/react-dom/src/__tests__/ReactDOMFloat-test.js
+76
@@ -4531,6 +4531,43 @@ body {
4531
);
4532
});
4533
4534
+ // @gate enableFloat
4535
+ it('respects attributes defined on the stylesheet element when preloading stylesheets during server rendering', async () => {
4536
+ await act(() => {
4537
+ const {pipe} = renderToPipeableStream(
4538
+ <html>
4539
+ <head>
4540
+ <link rel="stylesheet" fetchPriority="high" href="foo" />
4541
+ </head>
4542
+ <body>
4543
+ <link rel="stylesheet" fetchPriority="low" href="notaresource" />
4544
+ <div>hello world</div>
4545
+ </body>
4546
+ </html>,
4547
+ );
4548
+ pipe(writable);
4549
+ });
4550
+
4551
+ expect(getMeaningfulChildren(document)).toEqual(
4552
+ <html>
4553
+ <head>
4554
+ <link rel="preload" as="style" fetchpriority="high" href="foo" />
4555
+ <link
4556
+ rel="preload"
4557
+ as="style"
4558
+ fetchpriority="low"
4559
+ href="notaresource"
4560
+ />
4561
+ <link rel="stylesheet" fetchpriority="high" href="foo" />
4562
+ </head>
4563
+ <body>
4564
+ <link rel="stylesheet" fetchpriority="low" href="notaresource" />
4565
+ <div>hello world</div>
4566
+ </body>
4567
+ </html>,
4568
+ );
4569
+ });
4570
+
4571
// @gate enableFloat
4572
it('hoists stylesheet resources to the correct precedence', async () => {
4573
await act(() => {
@@ -5913,6 +5950,45 @@ background-color: green;
5950
);
5951
});
5952
5953
+ // @gate enableFloat
5954
+ it('respects attributes defined on the script element when preloading scripts during server rendering', async () => {
5955
+ await act(() => {
5956
+ const {pipe} = renderToPipeableStream(
5957
+ <html>
5958
+ <head />
5959
+ <body>
5960
+ <script src="foo" fetchPriority="high" nonce="1234" />
5961
+ <script src="bar" fetchPriority="low" nonce="1234" />
5962
+ hello world
5963
+ </body>
5964
+ </html>,
5965
+ );
5966
+ pipe(writable);
5967
+ });
5968
+
5969
+ expect(getMeaningfulChildren(document)).toEqual(
5970
+ <html>
5971
+ <head>
5972
+ <link
5973
+ rel="preload"
5974
+ href="foo"
5975
+ fetchpriority="high"
5976
+ nonce="1234"
5977
+ as="script"
5978
+ />
5979
+ <link
5980
+ rel="preload"
5981
+ href="bar"
5982
+ fetchpriority="low"
5983
+ nonce="1234"
5984
+ as="script"
5985
+ />
5986
+ </head>
5987
+ <body>hello world</body>
5988
+ </html>,
5989
+ );
5990
+ });
5991
+
5992
// @gate enableFloat
5993
it('does not create script resources when inside an <svg> context', async () => {
5994
await act(() => {