diff --git a/.changeset/fix-double-assistant-open.md b/.changeset/fix-double-assistant-open.md new file mode 100644 index 000000000..2e30c6fbf --- /dev/null +++ b/.changeset/fix-double-assistant-open.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Fix custom assistants (e.g. Kapa, Inkeep) being opened twice when clicking "Ask with …" in the search bar. diff --git a/packages/gitbook/src/components/Search/useSearchController.tsx b/packages/gitbook/src/components/Search/useSearchController.tsx index 485d5b047..1d37e4822 100644 --- a/packages/gitbook/src/components/Search/useSearchController.tsx +++ b/packages/gitbook/src/components/Search/useSearchController.tsx @@ -19,18 +19,23 @@ function useInitialAskBootstrap(props: { isLoaded: boolean; }) { const { asEmbeddable, assistants, initialAsk, isLoaded } = props; - const handledInitialAskRef = React.useRef(undefined); + const hasBootstrappedRef = React.useRef(false); React.useEffect(() => { if (asEmbeddable) return; + if (hasBootstrappedRef.current) return; if (assistants.length === 0) return; - if (initialAsk === null) return; - if (handledInitialAskRef.current === initialAsk) return; + if (!isLoaded) return; - // For simplicity we're only triggering the first assistant. - if (isLoaded) { + // Mark bootstrap as done once assistants and the body are ready, even if + // there is no initial ask. Subsequent `ask` changes come from user + // interactions (e.g. clicking "Ask with …" in the search bar, which also + // calls `assistant.open` directly) and must not re-trigger this effect. + hasBootstrappedRef.current = true; + + if (initialAsk !== null) { + // For simplicity we're only triggering the first assistant. assistants[0]?.open(initialAsk || undefined); - handledInitialAskRef.current = initialAsk; } }, [asEmbeddable, assistants, initialAsk, isLoaded]); }