From bf8e34a525ea54f8a8e4c72b7f90932b5cd21bed Mon Sep 17 00:00:00 2001 From: Zeno Kapitein Date: Wed, 5 Nov 2025 13:35:22 +0100 Subject: [PATCH] Add customizable suggested questions --- .changeset/ready-aliens-lose.md | 5 +++++ packages/gitbook/src/components/AI/useAI.tsx | 8 ++++++-- .../gitbook/src/components/AIChat/AIChat.tsx | 11 ++++++++++- .../Embeddable/EmbeddableRootLayout.tsx | 1 + .../src/components/Search/SearchContainer.tsx | 5 +++-- .../src/components/Search/useSearchResults.ts | 19 ++++++++++++++++++- .../src/components/SiteLayout/SiteLayout.tsx | 1 + 7 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 .changeset/ready-aliens-lose.md diff --git a/.changeset/ready-aliens-lose.md b/.changeset/ready-aliens-lose.md new file mode 100644 index 0000000000..dcfcc6c5af --- /dev/null +++ b/.changeset/ready-aliens-lose.md @@ -0,0 +1,5 @@ +--- +"gitbook": patch +--- + +Add customizable suggested questions diff --git a/packages/gitbook/src/components/AI/useAI.tsx b/packages/gitbook/src/components/AI/useAI.tsx index 29df1f2356..90bd0e7c24 100644 --- a/packages/gitbook/src/components/AI/useAI.tsx +++ b/packages/gitbook/src/components/AI/useAI.tsx @@ -15,6 +15,7 @@ import { useSearch } from '../Search/useSearch'; // Unify assistants configuration context with the assistants hook in one place export type AIConfig = { aiMode: CustomizationAIMode; + suggestions?: string[]; trademark: boolean; }; @@ -49,8 +50,11 @@ export type Assistant = Omit & { const AIContext = React.createContext(null); export function AIContextProvider(props: React.PropsWithChildren): React.ReactElement { - const { aiMode, trademark, children } = props; - const value = React.useMemo(() => ({ aiMode, trademark }), [aiMode, trademark]); + const { aiMode, trademark, suggestions, children } = props; + const value = React.useMemo( + () => ({ aiMode, trademark, suggestions }), + [aiMode, trademark, suggestions] + ); return {children}; } diff --git a/packages/gitbook/src/components/AIChat/AIChat.tsx b/packages/gitbook/src/components/AIChat/AIChat.tsx index 90484bfd5c..c9bd35d0cd 100644 --- a/packages/gitbook/src/components/AIChat/AIChat.tsx +++ b/packages/gitbook/src/components/AIChat/AIChat.tsx @@ -8,6 +8,7 @@ import { useHotkeys } from 'react-hotkeys-hook'; import { type AIChatController, type AIChatState, + useAI, useAIChatController, useAIChatState, } from '../AI'; @@ -32,6 +33,9 @@ import AIChatSuggestedQuestions from './AIChatSuggestedQuestions'; export function AIChat(props: { trademark: boolean }) { const { trademark } = props; + const { + config: { suggestions }, + } = useAI(); const language = useLanguage(); const chat = useAIChatState(); const chatController = useAIChatController(); @@ -96,7 +100,12 @@ export function AIChat(props: { trademark: boolean }) { - + diff --git a/packages/gitbook/src/components/Embeddable/EmbeddableRootLayout.tsx b/packages/gitbook/src/components/Embeddable/EmbeddableRootLayout.tsx index 104d50a3a6..d355adb668 100644 --- a/packages/gitbook/src/components/Embeddable/EmbeddableRootLayout.tsx +++ b/packages/gitbook/src/components/Embeddable/EmbeddableRootLayout.tsx @@ -35,6 +35,7 @@ export async function EmbeddableRootLayout({ > (); const recommendedQuestions: ResultType[] = []; + if (suggestions && suggestions.length > 0) { + suggestions.forEach((question) => { + questions.add(question); + }); + setResultsState({ + results: suggestions.map((question, index) => ({ + type: 'recommended-question', + id: `recommended-question-${index}`, + question, + })), + fetching: false, + error: false, + }); + return; + } + const timeout = setTimeout(async () => { if (cancelled) { return; diff --git a/packages/gitbook/src/components/SiteLayout/SiteLayout.tsx b/packages/gitbook/src/components/SiteLayout/SiteLayout.tsx index 23464fc075..deac249ddf 100644 --- a/packages/gitbook/src/components/SiteLayout/SiteLayout.tsx +++ b/packages/gitbook/src/components/SiteLayout/SiteLayout.tsx @@ -56,6 +56,7 @@ export async function SiteLayout(props: { >