diff --git a/packages/react-dom-bindings/src/client/ReactDOMComponent.js b/packages/react-dom-bindings/src/client/ReactDOMComponent.js
index 1b25e3727023..869cf6690ec4 100644
--- a/packages/react-dom-bindings/src/client/ReactDOMComponent.js
+++ b/packages/react-dom-bindings/src/client/ReactDOMComponent.js
@@ -756,6 +756,7 @@ function setProp(
case 'async':
case 'autoPlay':
case 'controls':
+ case 'credentialless':
case 'default':
case 'defer':
case 'disabled':
diff --git a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
index e654ea88007d..ba2e0b21d91a 100644
--- a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
+++ b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
@@ -1695,6 +1695,7 @@ function pushAttribute(
case 'async':
case 'autoPlay':
case 'controls':
+ case 'credentialless':
case 'default':
case 'defer':
case 'disabled':
diff --git a/packages/react-dom-bindings/src/shared/ReactDOMUnknownPropertyHook.js b/packages/react-dom-bindings/src/shared/ReactDOMUnknownPropertyHook.js
index f45e477d876f..aee7d9adb7df 100644
--- a/packages/react-dom-bindings/src/shared/ReactDOMUnknownPropertyHook.js
+++ b/packages/react-dom-bindings/src/shared/ReactDOMUnknownPropertyHook.js
@@ -208,6 +208,7 @@ function validateProperty(tagName, name, value, eventRegistry) {
case 'async':
case 'autoPlay':
case 'controls':
+ case 'credentialless':
case 'default':
case 'defer':
case 'disabled':
@@ -287,6 +288,7 @@ function validateProperty(tagName, name, value, eventRegistry) {
case 'async':
case 'autoPlay':
case 'controls':
+ case 'credentialless':
case 'default':
case 'defer':
case 'disabled':
diff --git a/packages/react-dom/src/__tests__/DOMPropertyOperations-test.js b/packages/react-dom/src/__tests__/DOMPropertyOperations-test.js
index ef09e49bf36c..5bbc2c8dbac8 100644
--- a/packages/react-dom/src/__tests__/DOMPropertyOperations-test.js
+++ b/packages/react-dom/src/__tests__/DOMPropertyOperations-test.js
@@ -160,6 +160,34 @@ describe('DOMPropertyOperations', () => {
expect(container.firstChild.hasAttribute('allowFullScreen')).toBe(false);
});
+ it('should set credentialless boolean attribute on iframes', async () => {
+ const container = document.createElement('div');
+ const root = ReactDOMClient.createRoot(container);
+ await act(() => {
+ root.render();
+ });
+ expect(container.firstChild.getAttribute('credentialless')).toBe('');
+ await act(() => {
+ root.render();
+ });
+ expect(container.firstChild.hasAttribute('credentialless')).toBe(false);
+ });
+
+ it('should set credentialless attribute when passed a string and warn', async () => {
+ const container = document.createElement('div');
+ const root = ReactDOMClient.createRoot(container);
+ await act(() => {
+ root.render();
+ });
+ assertConsoleErrorDev([
+ 'Received the string `true` for the boolean attribute `credentialless`. ' +
+ 'Although this works, it will not work as expected if you pass the string "false". ' +
+ 'Did you mean credentialless={true}?\n' +
+ ' in iframe (at **)',
+ ]);
+ expect(container.firstChild.getAttribute('credentialless')).toBe('');
+ });
+
it('should remove when setting custom attr to null', async () => {
const container = document.createElement('div');
const root = ReactDOMClient.createRoot(container);