diff --git a/packages/react-dom-bindings/src/client/ReactDOMComponent.js b/packages/react-dom-bindings/src/client/ReactDOMComponent.js
index ac95c91c596a8..05892c930e1ca 100644
--- a/packages/react-dom-bindings/src/client/ReactDOMComponent.js
+++ b/packages/react-dom-bindings/src/client/ReactDOMComponent.js
@@ -63,10 +63,7 @@ import {validateProperties as validateInputProperties} from '../shared/ReactDOMN
import {validateProperties as validateUnknownProperties} from '../shared/ReactDOMUnknownPropertyHook';
import sanitizeURL from '../shared/sanitizeURL';
-import {
- enableTrustedTypesIntegration,
- enableFilterEmptyStringAttributesDOM,
-} from 'shared/ReactFeatureFlags';
+import {enableTrustedTypesIntegration} from 'shared/ReactFeatureFlags';
import {
mediaEventTypes,
listenToNonDelegatedEvent,
@@ -400,35 +397,33 @@ function setProp(
// fallthrough
case 'src':
case 'href': {
- if (enableFilterEmptyStringAttributesDOM) {
- if (
- value === '' &&
- // is fine for "reload" links.
- !(tag === 'a' && key === 'href')
- ) {
- if (__DEV__) {
- if (key === 'src') {
- console.error(
- 'An empty string ("") was passed to the %s attribute. ' +
- 'This may cause the browser to download the whole page again over the network. ' +
- 'To fix this, either do not render the element at all ' +
- 'or pass null to %s instead of an empty string.',
- key,
- key,
- );
- } else {
- console.error(
- 'An empty string ("") was passed to the %s attribute. ' +
- 'To fix this, either do not render the element at all ' +
- 'or pass null to %s instead of an empty string.',
- key,
- key,
- );
- }
+ if (
+ value === '' &&
+ // is fine for "reload" links.
+ !(tag === 'a' && key === 'href')
+ ) {
+ if (__DEV__) {
+ if (key === 'src') {
+ console.error(
+ 'An empty string ("") was passed to the %s attribute. ' +
+ 'This may cause the browser to download the whole page again over the network. ' +
+ 'To fix this, either do not render the element at all ' +
+ 'or pass null to %s instead of an empty string.',
+ key,
+ key,
+ );
+ } else {
+ console.error(
+ 'An empty string ("") was passed to the %s attribute. ' +
+ 'To fix this, either do not render the element at all ' +
+ 'or pass null to %s instead of an empty string.',
+ key,
+ key,
+ );
}
- domElement.removeAttribute(key);
- break;
}
+ domElement.removeAttribute(key);
+ break;
}
if (
value == null ||
@@ -2489,53 +2484,52 @@ function diffHydratedGenericElement(
// fallthrough
case 'src':
case 'href':
- if (enableFilterEmptyStringAttributesDOM) {
- if (
- value === '' &&
- // is fine for "reload" links.
- !(tag === 'a' && propKey === 'href') &&
- !(tag === 'object' && propKey === 'data')
- ) {
- if (__DEV__) {
- if (propKey === 'src') {
- console.error(
- 'An empty string ("") was passed to the %s attribute. ' +
- 'This may cause the browser to download the whole page again over the network. ' +
- 'To fix this, either do not render the element at all ' +
- 'or pass null to %s instead of an empty string.',
- propKey,
- propKey,
- );
- } else {
- console.error(
- 'An empty string ("") was passed to the %s attribute. ' +
- 'To fix this, either do not render the element at all ' +
- 'or pass null to %s instead of an empty string.',
- propKey,
- propKey,
- );
- }
+ if (
+ value === '' &&
+ // is fine for "reload" links.
+ !(tag === 'a' && propKey === 'href') &&
+ !(tag === 'object' && propKey === 'data')
+ ) {
+ if (__DEV__) {
+ if (propKey === 'src') {
+ console.error(
+ 'An empty string ("") was passed to the %s attribute. ' +
+ 'This may cause the browser to download the whole page again over the network. ' +
+ 'To fix this, either do not render the element at all ' +
+ 'or pass null to %s instead of an empty string.',
+ propKey,
+ propKey,
+ );
+ } else {
+ console.error(
+ 'An empty string ("") was passed to the %s attribute. ' +
+ 'To fix this, either do not render the element at all ' +
+ 'or pass null to %s instead of an empty string.',
+ propKey,
+ propKey,
+ );
}
- hydrateSanitizedAttribute(
- domElement,
- propKey,
- propKey,
- null,
- extraAttributes,
- serverDifferences,
- );
- continue;
}
+ hydrateSanitizedAttribute(
+ domElement,
+ propKey,
+ propKey,
+ null,
+ extraAttributes,
+ serverDifferences,
+ );
+ continue;
+ } else {
+ hydrateSanitizedAttribute(
+ domElement,
+ propKey,
+ propKey,
+ value,
+ extraAttributes,
+ serverDifferences,
+ );
+ continue;
}
- hydrateSanitizedAttribute(
- domElement,
- propKey,
- propKey,
- value,
- extraAttributes,
- serverDifferences,
- );
- continue;
case 'action':
case 'formAction': {
const serverValue = domElement.getAttribute(propKey);
diff --git a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
index 1351a28db3aab..fe2e713d8a3ba 100644
--- a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
+++ b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
@@ -27,10 +27,7 @@ import {
import {Children} from 'react';
-import {
- enableFilterEmptyStringAttributesDOM,
- enableFizzExternalRuntime,
-} from 'shared/ReactFeatureFlags';
+import {enableFizzExternalRuntime} from 'shared/ReactFeatureFlags';
import type {
Destination,
@@ -1210,30 +1207,28 @@ function pushAttribute(
}
case 'src':
case 'href': {
- if (enableFilterEmptyStringAttributesDOM) {
- if (value === '') {
- if (__DEV__) {
- if (name === 'src') {
- console.error(
- 'An empty string ("") was passed to the %s attribute. ' +
- 'This may cause the browser to download the whole page again over the network. ' +
- 'To fix this, either do not render the element at all ' +
- 'or pass null to %s instead of an empty string.',
- name,
- name,
- );
- } else {
- console.error(
- 'An empty string ("") was passed to the %s attribute. ' +
- 'To fix this, either do not render the element at all ' +
- 'or pass null to %s instead of an empty string.',
- name,
- name,
- );
- }
+ if (value === '') {
+ if (__DEV__) {
+ if (name === 'src') {
+ console.error(
+ 'An empty string ("") was passed to the %s attribute. ' +
+ 'This may cause the browser to download the whole page again over the network. ' +
+ 'To fix this, either do not render the element at all ' +
+ 'or pass null to %s instead of an empty string.',
+ name,
+ name,
+ );
+ } else {
+ console.error(
+ 'An empty string ("") was passed to the %s attribute. ' +
+ 'To fix this, either do not render the element at all ' +
+ 'or pass null to %s instead of an empty string.',
+ name,
+ name,
+ );
}
- return;
}
+ return;
}
}
// Fall through to the last case which shouldn't remove empty strings.
@@ -1633,19 +1628,17 @@ function pushStartObject(
checkAttributeStringCoercion(propValue, 'data');
}
const sanitizedValue = sanitizeURL('' + propValue);
- if (enableFilterEmptyStringAttributesDOM) {
- if (sanitizedValue === '') {
- if (__DEV__) {
- console.error(
- 'An empty string ("") was passed to the %s attribute. ' +
- 'To fix this, either do not render the element at all ' +
- 'or pass null to %s instead of an empty string.',
- propKey,
- propKey,
- );
- }
- break;
+ if (sanitizedValue === '') {
+ if (__DEV__) {
+ console.error(
+ 'An empty string ("") was passed to the %s attribute. ' +
+ 'To fix this, either do not render the element at all ' +
+ 'or pass null to %s instead of an empty string.',
+ propKey,
+ propKey,
+ );
}
+ break;
}
target.push(
attributeSeparator,
@@ -3615,11 +3608,7 @@ export function pushStartInstance(
// Fast track very common tags
break;
case 'a':
- if (enableFilterEmptyStringAttributesDOM) {
- return pushStartAnchor(target, props);
- } else {
- break;
- }
+ return pushStartAnchor(target, props);
case 'g':
case 'p':
case 'li':
diff --git a/packages/react-dom/src/__tests__/ReactDOMComponent-test.js b/packages/react-dom/src/__tests__/ReactDOMComponent-test.js
index d37a4ecba6dc6..ce71a6334ee64 100644
--- a/packages/react-dom/src/__tests__/ReactDOMComponent-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMComponent-test.js
@@ -587,133 +587,131 @@ describe('ReactDOMComponent', () => {
expect(node.hasAttribute('data-foo')).toBe(false);
});
- if (ReactFeatureFlags.enableFilterEmptyStringAttributesDOM) {
- it('should not add an empty src attribute', async () => {
- const container = document.createElement('div');
- const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'An empty string ("") was passed to the src attribute. ' +
- 'This may cause the browser to download the whole page again over the network. ' +
- 'To fix this, either do not render the element at all ' +
- 'or pass null to src instead of an empty string.',
- );
- const node = container.firstChild;
- expect(node.hasAttribute('src')).toBe(false);
-
+ it('should not add an empty src attribute', async () => {
+ const container = document.createElement('div');
+ const root = ReactDOMClient.createRoot(container);
+ await expect(async () => {
await act(() => {
- root.render(
);
+ root.render(
);
});
- expect(node.hasAttribute('src')).toBe(true);
+ }).toErrorDev(
+ 'An empty string ("") was passed to the src attribute. ' +
+ 'This may cause the browser to download the whole page again over the network. ' +
+ 'To fix this, either do not render the element at all ' +
+ 'or pass null to src instead of an empty string.',
+ );
+ const node = container.firstChild;
+ expect(node.hasAttribute('src')).toBe(false);
- await expect(async () => {
- await act(() => {
- root.render(
);
- });
- }).toErrorDev(
- 'An empty string ("") was passed to the src attribute. ' +
- 'This may cause the browser to download the whole page again over the network. ' +
- 'To fix this, either do not render the element at all ' +
- 'or pass null to src instead of an empty string.',
- );
- expect(node.hasAttribute('src')).toBe(false);
+ await act(() => {
+ root.render(
);
});
+ expect(node.hasAttribute('src')).toBe(true);
- it('should not add an empty href attribute', async () => {
- const container = document.createElement('div');
- const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'An empty string ("") was passed to the href attribute. ' +
- 'To fix this, either do not render the element at all ' +
- 'or pass null to href instead of an empty string.',
- );
- const node = container.firstChild;
- expect(node.hasAttribute('href')).toBe(false);
+ await expect(async () => {
+ await act(() => {
+ root.render(
);
+ });
+ }).toErrorDev(
+ 'An empty string ("") was passed to the src attribute. ' +
+ 'This may cause the browser to download the whole page again over the network. ' +
+ 'To fix this, either do not render the element at all ' +
+ 'or pass null to src instead of an empty string.',
+ );
+ expect(node.hasAttribute('src')).toBe(false);
+ });
+ it('should not add an empty href attribute', async () => {
+ const container = document.createElement('div');
+ const root = ReactDOMClient.createRoot(container);
+ await expect(async () => {
await act(() => {
- root.render();
+ root.render();
});
- expect(node.hasAttribute('href')).toBe(true);
+ }).toErrorDev(
+ 'An empty string ("") was passed to the href attribute. ' +
+ 'To fix this, either do not render the element at all ' +
+ 'or pass null to href instead of an empty string.',
+ );
+ const node = container.firstChild;
+ expect(node.hasAttribute('href')).toBe(false);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- 'An empty string ("") was passed to the href attribute. ' +
- 'To fix this, either do not render the element at all ' +
- 'or pass null to href instead of an empty string.',
- );
- expect(node.hasAttribute('href')).toBe(false);
+ await act(() => {
+ root.render();
});
+ expect(node.hasAttribute('href')).toBe(true);
- it('should allow an empty href attribute on anchors', async () => {
- const container = document.createElement('div');
- const root = ReactDOMClient.createRoot(container);
+ await expect(async () => {
await act(() => {
- root.render();
+ root.render();
});
- const node = container.firstChild;
- expect(node.getAttribute('href')).toBe('');
+ }).toErrorDev(
+ 'An empty string ("") was passed to the href attribute. ' +
+ 'To fix this, either do not render the element at all ' +
+ 'or pass null to href instead of an empty string.',
+ );
+ expect(node.hasAttribute('href')).toBe(false);
+ });
+
+ it('should allow an empty href attribute on anchors', async () => {
+ const container = document.createElement('div');
+ const root = ReactDOMClient.createRoot(container);
+ await act(() => {
+ root.render();
});
+ const node = container.firstChild;
+ expect(node.getAttribute('href')).toBe('');
+ });
- it('should allow an empty action attribute', async () => {
- const container = document.createElement('div');
- const root = ReactDOMClient.createRoot(container);
- await act(() => {
- root.render(