Skip to content

Chained renderPageContributions drops the executor when the last component has hydrate disabled #2322

Description

@alansemenov

Problem

When page contributions are chained in the custom flow (the result of one renderPageContributions call is passed as the pageContributions option of the next), the executor script is lost as soon as a later call is made for a component that does not need JavaScript (SSR with hydrate: false, or Content Studio edit mode).

Example: a Header entry rendered with hydrate: true, followed by a static Footer entry rendered with hydrate: false. The first call adds the executor to bodyEnd. The second call strips it and never re-adds it, so Header is never hydrated even though its asset and JSON trigger are still in the page.

Cause

getAndMerge (src/main/resources/lib/enonic/react4xp/pageContributions/getAndMerge.ts) seeds the dedup control set with the executor tag so that it can be appended last. That removes it from the incoming contributions, and it is only appended again when the current call has suppressJS === false:

const controlSet = [
    executorEntry // Skip until manually added, must be last...
];
...
bodyEnd: getUniqueEntries([...], controlSet).concat(suppressJS ? [] : executorEntry)

Whether an earlier component in the chain needed the executor is not taken into account.

Expected

The executor must be kept (and stay last) whenever any component in the chain needs it, regardless of the suppressJS state of the last call.

Scope

Only the chained custom flow is affected. One controller per part is unaffected, since XP merges those contributions without removing anything. Present on 6.x, 7.x and master; introduced by 5ee46cd "Make sure executor is last".

Workaround: render the component that needs hydration last in the chain.

Reported by a customer in https://enonic.zendesk.com/agent/tickets/9392.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions