diff --git a/packages/@lwc/engine-core/src/framework/hydration.ts b/packages/@lwc/engine-core/src/framework/hydration.ts index 868c9b80d8..f55ae10f3d 100644 --- a/packages/@lwc/engine-core/src/framework/hydration.ts +++ b/packages/@lwc/engine-core/src/framework/hydration.ts @@ -664,7 +664,12 @@ function validateClassAttr( const elmClassName = getAttribute(elm, 'class'); - if (!isUndefined(className) && String(className) !== elmClassName) { + if ( + !isUndefined(className) && + String(className) !== elmClassName && + // No mismatch if SSR `class` attribute is missing and CSR `class` is the empty string + !(className === '' && isNull(elmClassName)) + ) { // className is used when class is bound to an expr. nodesAreCompatible = false; // stringify for pretty-printing diff --git a/packages/@lwc/integration-karma/test-hydration/mismatches/class-attr/empty-string/index.spec.js b/packages/@lwc/integration-karma/test-hydration/mismatches/class-attr/empty-string/index.spec.js new file mode 100644 index 0000000000..db4aec58ec --- /dev/null +++ b/packages/@lwc/integration-karma/test-hydration/mismatches/class-attr/empty-string/index.spec.js @@ -0,0 +1,17 @@ +export default { + props: { + classes: '', + }, + snapshot(target) { + const p = target.shadowRoot.querySelector('p'); + return { + p, + classes: p.className, + }; + }, + test(target, snapshots) { + const p = target.shadowRoot.querySelector('p'); + expect(p).toBe(snapshots.p); + expect(p.className).toBe(snapshots.classes); + }, +}; diff --git a/packages/@lwc/integration-karma/test-hydration/mismatches/class-attr/empty-string/x/main/main.html b/packages/@lwc/integration-karma/test-hydration/mismatches/class-attr/empty-string/x/main/main.html new file mode 100644 index 0000000000..213b575922 --- /dev/null +++ b/packages/@lwc/integration-karma/test-hydration/mismatches/class-attr/empty-string/x/main/main.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/packages/@lwc/integration-karma/test-hydration/mismatches/class-attr/empty-string/x/main/main.js b/packages/@lwc/integration-karma/test-hydration/mismatches/class-attr/empty-string/x/main/main.js new file mode 100644 index 0000000000..837fcfe574 --- /dev/null +++ b/packages/@lwc/integration-karma/test-hydration/mismatches/class-attr/empty-string/x/main/main.js @@ -0,0 +1,4 @@ +import { LightningElement, api } from 'lwc'; +export default class Main extends LightningElement { + @api classes; +}