Skip to content

bug: scoped SSR hydration reorders children when the child is defined first #6926

Description

@wessmeister

Prerequisites

Stencil Version

4.45.1

Current Behavior

With shadow: true components and serializeShadowRoot: 'scoped', defining the child before its parent moves following text ahead of the child during hydration.

The parent renders <span><slot /></span>. The child renders <span>Child content</span>. Direct renderToString() receives:

<slot-parent><scoped-child></scoped-child> trailing text</slot-parent>

Server HTML has the correct order. Calling the generated child's defineCustomElement() followed by the parent's produces:

<slot-parent> trailing text<scoped-child></scoped-child></slot-parent>

Defining the parent first preserves the order. The reproduction uses raw Stencil hydrate output and custom elements without React or Next.js.

Expected Behavior

Preserve light DOM order regardless of custom-element definition order.

System Info

System: node 22.23.1
Platform: darwin (25.5.0)
CPU Model: Apple M4 Pro (12 cpus)
Compiler: <reproduction>/node_modules/.pnpm/@stencil+core@4.45.1/node_modules/@stencil/core/compiler/stencil.js
Build: 1790157998
Stencil: 4.45.1
TypeScript: 5.8.3
Rollup: 4.44.0
Parse5: 7.2.1
jQuery: 4.0.0-pre
Terser: 5.37.0
Browser: Chromium 151.0.7922.34

Steps to Reproduce

pnpm install --frozen-lockfile
pnpm run build:stencil
node scripts/core-repro.mjs
  1. Open http://localhost:3001/. The text appears before the child. The displayed childNodes confirm this order.
  2. Open http://localhost:3001/parent-first. Only definition order changes; the child now correctly precedes the text.

Code Reproduction URL

https://github.com/wessmeister/stencil-scoped-ssr-repro/tree/fd471e8ec96115a512c02eebcc15028fda46bdb6

Additional Information

Also reproduced with 4.41.0 and 4.41.2.

Unlike the named-slot ordering cases in #6293 and #6299, this uses one default slot and depends on definition order.

clientHydrate consumes the current host's parent-owned c-id during that host's own hydration. Draft fix #6927 leaves that annotation for the enclosing component and continues processing descendants. Regression tests and built-package browser checks preserve both definition orders. The reproduction includes instructions for testing the fix.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions