Skip to content

Search Blocks: fix result and filter lists not rendering after results load#49876

Open
lancewillett wants to merge 2 commits into
trunkfrom
fix/search-blocks-data-wp-each-rerender
Open

Search Blocks: fix result and filter lists not rendering after results load#49876
lancewillett wants to merge 2 commits into
trunkfrom
fix/search-blocks-data-wp-each-rerender

Conversation

@lancewillett

@lancewillett lancewillett commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Related to FG-38

What

Fix the Search Blocks result list and filter buckets rendering empty after results load.

Why

Once @wordpress/interactivity is supplied by the host runtime (externalized from the build), the data-wp-each directive stops re-rendering a list when the bound array's reference is replaced after the initial render. The store replaced the arrays on every search (state.results = ( data.results ?? [] ).map( ... ), state.aggregations = remapAggregationsToFilterKeys( ... )).

At hydration state.results is the empty seeded array, so the each subscribes to that array instance and renders zero items. The fetch then assigns a brand-new array, so the each never re-renders — even though the store data, the result count, and scalar (data-wp-text / data-wp-bind) bindings all update correctly. Result: the results list and the filter buckets stay empty.

Fix

  • Mutate the each-bound arrays/objects in place instead of reassigning, so the runtime keeps tracking the same container — results, aggregations, retainedFilterOptions, and loadMore's append (replaceStateArray / replaceStateObject). This is the load-bearing change.
  • Declare those slots in the client store state so there is always a stable container.
  • Correct the result/citation templates' data-wp-keydata-wp-each-key; data-wp-each reads its key from its own each-key directive, so data-wp-key on the <template> was a no-op.

Testing

  • Added a store test asserting the each-bound containers keep their reference (in-place mutation) with updated contents after search(); all search-blocks JS tests pass (597).
  • Verified end-to-end against a live page running the host Interactivity runtime that exhibits the bug: with the fix, the result list and filter facets render again (before: skeletons only / zero items; after: full results + facets).

🤖 Generated with Claude Code

…s load

After @wordpress/interactivity was externalized, the Search Blocks run against
the host Interactivity runtime's data-wp-each. That runtime stops re-rendering
a data-wp-each list when the bound array's reference is swapped after the
initial (empty) render — which is what the store did on every search
(`state.results = mapped`). Results and filter buckets rendered nothing even
though the store data, the count, and scalar bindings all updated.

Mutate the each-bound arrays/objects in place (results, aggregations,
retainedFilterOptions, and loadMore's append) instead of reassigning, so the
runtime keeps tracking the same container; declare those slots on the client
store state for a stable container; and correct the templates' data-wp-key →
data-wp-each-key (data-wp-each requires its own key directive).

Verified against the live runtime: results and filter facets render again.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WoA dev site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin (Jetpack), and enable the fix/search-blocks-data-wp-each-rerender branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack fix/search-blocks-data-wp-each-rerender

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

@github-actions github-actions Bot added [Package] Search Contains core Search functionality for Jetpack and Search plugins [Tests] Includes Tests labels Jun 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • 🔴 Add a "[Status]" label (In Progress, Needs Review, ...).
  • 🔴 Add testing instructions.
  • 🔴 Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖


🔴 Action required: Please include detailed testing steps, explaining how to test your change, like so:

## Testing instructions:

* Go to '..'
*

🔴 Action required: We would recommend that you add a section to the PR description to specify whether this PR includes any changes to data or privacy, like so:

## Does this pull request change what data or activity we track or use?

My PR adds *x* and *y*.

Follow this PR Review Process:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!

@github-actions github-actions Bot added the [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. label Jun 24, 2026
@jp-launch-control

jp-launch-control Bot commented Jun 24, 2026

Copy link
Copy Markdown

Code Coverage Summary

Coverage changed in 1 file.

File Coverage Δ% Δ Uncovered
projects/packages/search/src/search-blocks/store/index.js 500/578 (86.51%) 0.24% 0 💚

Full summary · PHP report · JS report

@lancewillett lancewillett requested a review from kangzj June 24, 2026 04:03
@lancewillett

Copy link
Copy Markdown
Contributor Author

@kangzj Requested review (this PR is AI-generated, so likely needs some more testing and validation). See FG-38 for the original report.

Drop the unreachable type-guard branches from replaceStateArray /
replaceStateObject: the slots they touch (results, aggregations,
retainedFilterOptions) are declared on the initial state, so they are always
the right type. replaceStateObject now deletes only keys absent from the next
value before assigning, which also makes a next === current call a safe no-op.
This closes the coverage gap CI flagged on the removed branches.

Add three tests asserting the each-bound containers keep their reference
(toBe) while their contents update: overwriting a kept aggregation key,
dropping a stale key, and loadMore appending in place.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lancewillett

Copy link
Copy Markdown
Contributor Author

1216fc7 — Simplified the in-place helpers (removed unreachable type-guard branches, which closes the code-coverage gap CI flagged) and added 3 reference-stability tests: kept-key overwrite, stale-key drop, and loadMore in-place append. All assert toBe reference identity plus content. 600 search-blocks JS tests pass; eslint clean.

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

Labels

[Package] Search Contains core Search functionality for Jetpack and Search plugins [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. [Tests] Includes Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant