mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-17 08:05:19 +00:00
Add assistantName property to Docs Embed (#4095)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@gitbook/embed": minor
|
||||
---
|
||||
|
||||
Support `assistantName` property to override Assistant name
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"gitbook": patch
|
||||
---
|
||||
|
||||
Refactor embeddable context to merge local & site properties in one unified way
|
||||
@@ -49,6 +49,7 @@ GitBook('configure', {
|
||||
}
|
||||
],
|
||||
greeting: { title: 'Welcome!', subtitle: 'How can I help?' },
|
||||
assistantName: 'Support Assistant',
|
||||
suggestions: ['What is GitBook?', 'How do I get started?'],
|
||||
tools: [/* ... */],
|
||||
closeButton: true,
|
||||
@@ -100,6 +101,7 @@ frame.configure({
|
||||
}
|
||||
],
|
||||
greeting: { title: 'Welcome!', subtitle: 'How can I help?' },
|
||||
assistantName: 'Support Assistant',
|
||||
suggestions: ['What is GitBook?', 'How do I get started?'],
|
||||
tools: [/* ... */],
|
||||
closeButton: true
|
||||
@@ -126,6 +128,7 @@ import { GitBookProvider, GitBookFrame } from '@gitbook/embed/react';
|
||||
}}
|
||||
tabs={['assistant', 'docs']}
|
||||
greeting={{ title: 'Welcome!', subtitle: 'How can I help?' }}
|
||||
assistantName="Support Assistant"
|
||||
suggestions={['What is GitBook?', 'How do I get started?']}
|
||||
actions={[
|
||||
{
|
||||
@@ -328,6 +331,18 @@ greeting: {
|
||||
}
|
||||
```
|
||||
|
||||
### `assistantName`
|
||||
|
||||
Available in: Standalone script, NPM package, React components
|
||||
|
||||
Override the assistant name displayed in the chat header and assistant entry points (for example, sidebar tabs and action labels). This name will be limited to 32 characters to prevent text overflow.
|
||||
|
||||
- **Type**: `string`
|
||||
|
||||
```javascript
|
||||
assistantName: 'Support Assistant'
|
||||
```
|
||||
|
||||
### `suggestions`
|
||||
|
||||
Available in: Standalone script, NPM package, React components
|
||||
|
||||
@@ -62,6 +62,12 @@ export type GitBookEmbeddableConfiguration = {
|
||||
subtitle: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Override the assistant name displayed in the UI.
|
||||
* Limited to 32 characters.
|
||||
*/
|
||||
assistantName?: string;
|
||||
|
||||
/** Suggestions of questions to be displayed in the welcome page. */
|
||||
suggestions: string[];
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ export function GitBookFrame(props: GitBookFrameProps) {
|
||||
tabs = ['assistant', 'docs'],
|
||||
trademark = true,
|
||||
closeButton = false,
|
||||
assistantName,
|
||||
} = props;
|
||||
|
||||
const frameRef = useRef<HTMLIFrameElement>(null);
|
||||
@@ -50,8 +51,19 @@ export function GitBookFrame(props: GitBookFrameProps) {
|
||||
tools,
|
||||
closeButton,
|
||||
trademark,
|
||||
assistantName,
|
||||
});
|
||||
}, [gitbookFrame, actions, greeting, suggestions, tools, tabs, closeButton, trademark]);
|
||||
}, [
|
||||
gitbookFrame,
|
||||
actions,
|
||||
greeting,
|
||||
suggestions,
|
||||
tools,
|
||||
tabs,
|
||||
closeButton,
|
||||
trademark,
|
||||
assistantName,
|
||||
]);
|
||||
|
||||
return (
|
||||
<iframe
|
||||
|
||||
@@ -17,6 +17,7 @@ export type AIConfig = {
|
||||
aiMode: CustomizationAIMode;
|
||||
suggestions?: string[];
|
||||
trademark: boolean;
|
||||
assistantName?: string;
|
||||
greeting?: {
|
||||
title: string;
|
||||
subtitle: string;
|
||||
@@ -54,10 +55,10 @@ export type Assistant = Omit<GitBookAssistant, 'icon'> & {
|
||||
const AIContext = React.createContext<AIConfig | null>(null);
|
||||
|
||||
export function AIContextProvider(props: React.PropsWithChildren<AIConfig>): React.ReactElement {
|
||||
const { aiMode, trademark, suggestions, greeting, children } = props;
|
||||
const { aiMode, trademark, suggestions, greeting, assistantName, children } = props;
|
||||
const value = React.useMemo(
|
||||
() => ({ aiMode, trademark, suggestions, greeting }),
|
||||
[aiMode, trademark, suggestions, greeting]
|
||||
() => ({ aiMode, trademark, suggestions, greeting, assistantName }),
|
||||
[aiMode, trademark, suggestions, greeting, assistantName]
|
||||
);
|
||||
return <AIContext.Provider value={value}>{children}</AIContext.Provider>;
|
||||
}
|
||||
@@ -91,7 +92,7 @@ export function useAI(): AIContext {
|
||||
if (config.aiMode === CustomizationAIMode.Assistant) {
|
||||
assistants.push({
|
||||
id: 'gitbook-assistant',
|
||||
label: getAIChatName(language, config.trademark),
|
||||
label: config.assistantName ?? getAIChatName(language, config.trademark),
|
||||
icon: (
|
||||
<AIChatIcon
|
||||
state={chat.loading ? 'thinking' : 'default'}
|
||||
|
||||
@@ -92,7 +92,7 @@ export function AIChat() {
|
||||
<AIChatDynamicIcon trademark={config.trademark} />
|
||||
<EmbeddableFrameHeaderMain>
|
||||
<EmbeddableFrameTitle>
|
||||
{getAIChatName(language, config.trademark)}
|
||||
{config.assistantName ?? getAIChatName(language, config.trademark)}
|
||||
</EmbeddableFrameTitle>
|
||||
<AIChatSubtitle chat={chat} />
|
||||
</EmbeddableFrameHeaderMain>
|
||||
|
||||
@@ -66,7 +66,7 @@ export function EmbeddableAIChat(props: EmbeddableAIChatProps) {
|
||||
|
||||
const tabsRef = React.useRef<HTMLDivElement>(null);
|
||||
const hasDocsTab = embedConfig.tabs.includes('docs');
|
||||
const trademark = siteConfig.trademark && (embedConfig.trademark ?? true);
|
||||
const trademark = siteConfig.trademark;
|
||||
const currentLinkContext = use(LinkContext);
|
||||
const linkContext: LinkContextType = useMemo(
|
||||
() =>
|
||||
@@ -100,7 +100,7 @@ export function EmbeddableAIChat(props: EmbeddableAIChatProps) {
|
||||
) : null}
|
||||
<EmbeddableFrameHeaderMain>
|
||||
<EmbeddableFrameTitle>
|
||||
{getAIChatName(language, trademark)}
|
||||
{siteConfig.assistantName ?? getAIChatName(language, trademark)}
|
||||
</EmbeddableFrameTitle>
|
||||
<AIChatSubtitle chat={chat} />
|
||||
</EmbeddableFrameHeaderMain>
|
||||
@@ -113,8 +113,8 @@ export function EmbeddableAIChat(props: EmbeddableAIChatProps) {
|
||||
<AIChatBody
|
||||
chatController={chatController}
|
||||
chat={chat}
|
||||
suggestions={embedConfig.suggestions}
|
||||
greeting={embedConfig.greeting}
|
||||
suggestions={siteConfig.suggestions}
|
||||
greeting={siteConfig.greeting}
|
||||
trademark={trademark}
|
||||
/>
|
||||
</LinkContext>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
'use client';
|
||||
|
||||
import { type AIConfig, AIContextProvider } from '@/components/AI';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import { useEmbeddableConfiguration } from './EmbeddableIframeAPI';
|
||||
|
||||
type EmbeddableAIContextProviderProps = PropsWithChildren<AIConfig>;
|
||||
|
||||
/**
|
||||
* AI context provider for embeddable routes.
|
||||
* Merges the static site AI config with runtime embed configuration updates.
|
||||
*/
|
||||
export function EmbeddableAIContextProvider(props: EmbeddableAIContextProviderProps) {
|
||||
const { aiMode, suggestions, greeting, trademark, children } = props;
|
||||
const embedConfig = useEmbeddableConfiguration();
|
||||
|
||||
return (
|
||||
<AIContextProvider
|
||||
aiMode={aiMode}
|
||||
suggestions={embedConfig.suggestions ?? suggestions}
|
||||
greeting={embedConfig.greeting ?? greeting}
|
||||
trademark={trademark && (embedConfig.trademark ?? true)}
|
||||
assistantName={embedConfig.assistantName?.substring(0, 32)} // Limit to 32 characters
|
||||
>
|
||||
{children}
|
||||
</AIContextProvider>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import { AIContextProvider } from '@/components/AI';
|
||||
import { CustomizationRootLayout } from '@/components/RootLayout';
|
||||
import {
|
||||
SiteLayoutClientContexts,
|
||||
@@ -11,6 +10,7 @@ import { SiteInsightsTrademarkPlacement } from '@gitbook/api';
|
||||
import { SpaceLayoutServerContext } from '../SpaceLayout';
|
||||
import { Trademark } from '../TableOfContents/Trademark';
|
||||
import { NavigationLoader } from '../primitives/NavigationLoader';
|
||||
import { EmbeddableAIContextProvider } from './EmbeddableAIContextProvider';
|
||||
import { EmbeddableIframeAPI } from './EmbeddableIframeAPI';
|
||||
import { IfEmbeddableTrademark } from './EmbeddableTrademark';
|
||||
|
||||
@@ -41,7 +41,7 @@ export async function EmbeddableRootLayout({
|
||||
contextId={context.contextId}
|
||||
proxyOrigin={context.site.proxy?.origin}
|
||||
>
|
||||
<AIContextProvider
|
||||
<EmbeddableAIContextProvider
|
||||
aiMode={context.customization.ai.mode}
|
||||
suggestions={context.customization.ai.suggestions}
|
||||
trademark={context.customization.trademark.enabled}
|
||||
@@ -72,7 +72,7 @@ export async function EmbeddableRootLayout({
|
||||
baseURL={context.linker.toPathInSite('~gitbook/embed/')}
|
||||
/>
|
||||
</SpaceLayoutServerContext>
|
||||
</AIContextProvider>
|
||||
</EmbeddableAIContextProvider>
|
||||
</SiteLayoutClientContexts>
|
||||
</CustomizationRootLayout>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user