Skip to content

Commit 8e1012f

Browse files
fix(next): insert empty initial results for page with no widgets (#6595)
1 parent b69fd63 commit 8e1012f

File tree

4 files changed

+51
-32
lines changed

4 files changed

+51
-32
lines changed

packages/react-instantsearch-nextjs/src/InitializePromise.tsx renamed to packages/react-instantsearch-nextjs/src/InitializePromise.ts

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import { getInitialResults } from 'instantsearch.js/es/lib/server';
22
import { resetWidgetId, walkIndex } from 'instantsearch.js/es/lib/utils';
33
import { ServerInsertedHTMLContext } from 'next/navigation';
4-
import React, { useContext } from 'react';
4+
import { useContext } from 'react';
55
import {
66
useInstantSearchContext,
77
useRSCContext,
88
wrapPromiseWithState,
99
} from 'react-instantsearch-core';
1010

11-
import { htmlEscapeJsonString } from './htmlEscape';
11+
import { createInsertHTML } from './createInsertHTML';
1212

1313
import type {
14-
InitialResults,
1514
SearchOptions,
1615
CompositionClient,
1716
SearchClient,
@@ -26,33 +25,6 @@ type InitializePromiseProps = {
2625
nonce?: string;
2726
};
2827

29-
const createInsertHTML =
30-
({
31-
options,
32-
results,
33-
nonce,
34-
}: {
35-
options: { inserted: boolean };
36-
results: InitialResults;
37-
nonce?: string;
38-
}) =>
39-
() => {
40-
if (options.inserted) {
41-
return <></>;
42-
}
43-
options.inserted = true;
44-
return (
45-
<script
46-
nonce={nonce}
47-
dangerouslySetInnerHTML={{
48-
__html: `window[Symbol.for("InstantSearchInitialResults")] = ${htmlEscapeJsonString(
49-
JSON.stringify(results)
50-
)}`,
51-
}}
52-
/>
53-
);
54-
};
55-
5628
export function InitializePromise({ nonce }: InitializePromiseProps) {
5729
const search = useInstantSearchContext();
5830
const waitForResultsRef = useRSCContext();

packages/react-instantsearch-nextjs/src/InstantSearchNext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ This message will only be displayed in development mode.`
7676
<InstantSearch {...instantSearchProps} routing={routing!}>
7777
{isServer && <InitializePromise nonce={nonce} />}
7878
{children}
79-
{isServer && <TriggerSearch />}
79+
{isServer && <TriggerSearch nonce={nonce} />}
8080
</InstantSearch>
8181
</ServerOrHydrationProvider>
8282
);

packages/react-instantsearch-nextjs/src/TriggerSearch.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1+
import { ServerInsertedHTMLContext } from 'next/navigation';
2+
import { useContext } from 'react';
13
import {
24
useInstantSearchContext,
35
useRSCContext,
46
} from 'react-instantsearch-core';
57

6-
export function TriggerSearch() {
8+
import { createInsertHTML } from './createInsertHTML';
9+
10+
export function TriggerSearch({ nonce }: { nonce?: string }) {
711
const instantsearch = useInstantSearchContext();
812
const waitForResultsRef = useRSCContext();
13+
const insertHTML =
14+
useContext(ServerInsertedHTMLContext) ||
15+
(() => {
16+
throw new Error('Missing ServerInsertedHTMLContext');
17+
});
918

1019
if (waitForResultsRef?.current?.status === 'pending') {
1120
if (instantsearch._hasSearchWidget) {
@@ -16,6 +25,12 @@ export function TriggerSearch() {
1625
}
1726
}
1827
instantsearch._hasRecommendWidget && instantsearch.mainHelper?.recommend();
28+
29+
// If there are no widgets, we inject empty initial results instantly
30+
if (!instantsearch._hasSearchWidget && !instantsearch._hasRecommendWidget) {
31+
const options = { inserted: false };
32+
insertHTML(createInsertHTML({ options, results: {}, nonce }));
33+
}
1934
}
2035

2136
return null;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from 'react';
2+
3+
import { htmlEscapeJsonString } from './htmlEscape';
4+
5+
import type { InitialResults } from 'instantsearch.js';
6+
7+
export const createInsertHTML =
8+
({
9+
options,
10+
results,
11+
nonce,
12+
}: {
13+
options: { inserted: boolean };
14+
results: InitialResults;
15+
nonce?: string;
16+
}) =>
17+
() => {
18+
if (options.inserted) {
19+
return <></>;
20+
}
21+
options.inserted = true;
22+
return (
23+
<script
24+
nonce={nonce}
25+
dangerouslySetInnerHTML={{
26+
__html: `window[Symbol.for("InstantSearchInitialResults")] = ${htmlEscapeJsonString(
27+
JSON.stringify(results)
28+
)}`,
29+
}}
30+
/>
31+
);
32+
};

0 commit comments

Comments
 (0)