Repository: facebook/react
Pull request: [Float][Fizz][Fiber] support type for ReactDOM.preload() options

preloads often need to come with a type attribute which allows browsers to decide if they support the preloading resource's type. If the type is unsupported the preload will not be fetched by the Browser. This change adds support for `type` in `ReactDOM.preload()` as a string option.

Changed files:
filename: packages/react-dom-bindings/src/client/ReactDOMFloatClient.js
patch: @@ -253,7 +253,12 @@ function preconnect(href: string, options?: {crossOrigin?: string}) {
 //      ReactDOM.preload
 // --------------------------------------
 type PreloadAs = ResourceType;
-type PreloadOptions = {as: PreloadAs, crossOrigin?: string, integrity?: string};
+type PreloadOptions = {
+  as: PreloadAs,
+  crossOrigin?: string,
+  integrity?: string,
+  type?: string,
+};
 function preload(href: string, options: PreloadOptions) {
   if (__DEV__) {
     validatePreloadArguments(href, options);
@@ -309,6 +314,7 @@ function preloadPropsFromPreloadOptions(
     as,
     crossOrigin: as === 'font' ? '' : options.crossOrigin,
     integrity: options.integrity,
+    type: options.type,
   };
 }
 

filename: packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js
patch: @@ -4344,7 +4344,7 @@ type PreloadOptions = {
   as: PreloadAs,
   crossOrigin?: string,
   integrity?: string,
-  media?: string,
+  type?: string,
 };
 export function preload(href: string, options: PreloadOptions) {
   if (!currentResources) {
@@ -4709,6 +4709,7 @@ function preloadPropsFromPreloadOptions(
     href,
     crossOrigin: as === 'font' ? '' : options.crossOrigin,
     integrity: options.integrity,
+    type: options.type,
   };
 }
 

filename: packages/react-dom/src/__tests__/ReactDOMFloat-test.js
patch: @@ -2267,7 +2267,7 @@ body {
   // @gate enableFloat
   it('always enforces crossOrigin "anonymous" for font preloads', async () => {
     function App() {
-      ReactDOM.preload('foo', {as: 'font'});
+      ReactDOM.preload('foo', {as: 'font', type: 'font/woff2'});
       ReactDOM.preload('bar', {as: 'font', crossOrigin: 'foo'});
       ReactDOM.preload('baz', {as: 'font', crossOrigin: 'use-credentials'});
       ReactDOM.preload('qux', {as: 'font', crossOrigin: 'anonymous'});
@@ -2285,7 +2285,13 @@ body {
     expect(getMeaningfulChildren(document)).toEqual(
       <html>
         <head>
-          <link rel="preload" as="font" href="foo" crossorigin="" />
+          <link
+            rel="preload"
+            as="font"
+            href="foo"
+            crossorigin=""
+            type="font/woff2"
+          />
           <link rel="preload" as="font" href="bar" crossorigin="" />
           <link rel="preload" as="font" href="baz" crossorigin="" />
           <link rel="preload" as="font" href="qux" crossorigin="" />
@@ -2488,6 +2494,7 @@ body {
 
       function ClientApp() {
         ReactDOM.preload('foo', {as: 'style'});
+        ReactDOM.preload('font', {as: 'font', type: 'font/woff2'});
         React.useInsertionEffect(() => ReactDOM.preload('bar', {as: 'script'}));
         React.useLayoutEffect(() => ReactDOM.preload('baz', {as: 'font'}));
         React.useEffect(() => ReactDOM.preload('qux', {as: 'style'}));
@@ -2507,6 +2514,13 @@ body {
         <html>
           <head>
             <link rel="preload" as="style" href="foo" />
+            <link
+              rel="preload"
+              as="font"
+              href="font"
+              crossorigin=""
+              type="font/woff2"
+            />
             <link rel="preload" as="font" href="baz" crossorigin="" />
             <link rel="preload" as="style" href="qux" />
           </head>