diff --git a/src/lib/InstantSearch.ts b/src/lib/InstantSearch.ts index 7b34d6a5769..26bbba88bbf 100644 --- a/src/lib/InstantSearch.ts +++ b/src/lib/InstantSearch.ts @@ -425,7 +425,10 @@ See ${createDocumentationLink({ // This Helper is used for the queries, we don't care about its state. The // states are managed at the `index` level. We use this Helper to create // DerivedHelper scoped into the `index` widgets. - const mainHelper = algoliasearchHelper(this.client, this.indexName); + // In Vue InstantSearch' hydrate, a main helper gets set before start, so + // we need to respect this helper as a way to keep all listeners correct. + const mainHelper = + this.mainHelper || algoliasearchHelper(this.client, this.indexName); mainHelper.search = () => { // This solution allows us to keep the exact same API for the users but diff --git a/src/lib/__tests__/InstantSearch-test.tsx b/src/lib/__tests__/InstantSearch-test.tsx index 2ae317b2693..649659036e1 100644 --- a/src/lib/__tests__/InstantSearch-test.tsx +++ b/src/lib/__tests__/InstantSearch-test.tsx @@ -850,6 +850,28 @@ describe('start', () => { See documentation: https://www.algolia.com/doc/api-reference/widgets/instantsearch/js/" `); }); + + it('keeps a mainHelper already set on the instance (Vue SSR)', () => { + const searchClient = createSearchClient(); + const instance = new InstantSearch({ + indexName: 'indexName', + searchClient, + }); + + const helper = algoliasearchHelper(searchClient, ''); + + // explicitly setting the mainHelper before start is used to force render to + // happen before the results of the first search are done. We need to make + // sure no extra helper is created, as that can cause certain things (like routing) + // to be listening to the wrong helper. + instance.mainHelper = helper; + + expect(instance.mainHelper).toBe(helper); + + instance.start(); + + expect(instance.mainHelper).toBe(helper); + }); }); describe('dispose', () => {