lwc icon indicating copy to clipboard operation
lwc copied to clipboard

[SSR] `engine-server` prop/attr reflection not matching `engine-dom`

Open nolanlawson opened this issue 10 months ago • 4 comments

While looking into some SSR v2 test failures (namely 'attribute-global-html/as-component-prop/*), I wanted to test that engine-server actually matches engine-dom's behavior for HTML global / ARIA property-to-attribute reflection.

It seems it does not. In particular, there are two cases:

Case 1: the prop is declared internally to the component, but without using @api, e.g.:

export default class extends LightningElement {
  title
  ariaLabel
}

Case 2: the prop is not declared internally to the component at all.

In both cases, if a parent component passes in a prop using template HTML, and if the child component renders its prop using its own template HTML, then the results do not match between engine-dom and engine-server, leading to hydration mismatches. Non-matching props:

Case 1:

Click to see
  • accessKey
  • ariaActiveDescendant
  • ariaAtomic
  • ariaAutoComplete
  • ariaBusy
  • ariaChecked
  • ariaColCount
  • ariaColIndex
  • ariaColSpan
  • ariaControls
  • ariaCurrent
  • ariaDescribedBy
  • ariaDetails
  • ariaDisabled
  • ariaErrorMessage
  • ariaExpanded
  • ariaFlowTo
  • ariaHasPopup
  • ariaHidden
  • ariaInvalid
  • ariaKeyShortcuts
  • ariaLabel
  • ariaLabelledBy
  • ariaLevel
  • ariaLive
  • ariaModal
  • ariaMultiLine
  • ariaMultiSelectable
  • ariaOrientation
  • ariaOwns
  • ariaPlaceholder
  • ariaPosInSet
  • ariaPressed
  • ariaReadOnly
  • ariaRelevant
  • ariaRequired
  • ariaRoleDescription
  • ariaRowCount
  • ariaRowIndex
  • ariaRowSpan
  • ariaSelected
  • ariaSetSize
  • ariaSort
  • ariaValueMax
  • ariaValueMin
  • ariaValueNow
  • ariaValueText
  • dir
  • draggable
  • hidden
  • id
  • lang
  • role
  • spellcheck
  • tabIndex
  • title

Case 2:

  • dir
  • draggable
  • hidden
  • tabIndex

Repro: 0a1ef1555

This repro is based on existing fixture tests in engine-server.

nolanlawson avatar Jan 09 '25 23:01 nolanlawson

This issue has been linked to a new work item: W-17572462

git2gus[bot] avatar Jan 09 '25 23:01 git2gus[bot]

I also suspect that we are not rendering the right attributes on child components, and that hydration mismatch detection is not detecting this correctly, but I'd need to dig deeper to confirm.

nolanlawson avatar Jan 10 '25 00:01 nolanlawson

We are definitely not rendering the right attributes for child components. And unfortunately hydration does not detect this, because it considers them properties rather than attributes.

So for example, this repro renders the following in CSR:

<x-child aria-label="foo" title="bar" dir="foo" draggable="true" hidden="" tabindex="0">

But engine-server renders the following (repro: 164700d7f):

<x-child aria-label="foo" title="bar" dir="foo" draggable="foo" tabindex="foo">

So the draggable, hidden, and tabindex are not rendering properly.

nolanlawson avatar Jan 14 '25 00:01 nolanlawson

  • This has been fixed for ssr-compiler, which now aligns with engine-dom and there are no hydration errors for the affected attributes.
  • However, the issue is still present for the legacy engine-server. Given engine-server will soon be deprecated, this issue is not a priority.
  • Hydration tests have been added here, with an exception made to account for the V1 (engine-server) hydration issues.

jhefferman-sfdc avatar Mar 11 '25 15:03 jhefferman-sfdc