mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-17 08:05:19 +00:00
Docs Embed: Make trademark optional (#4079)
Co-authored-by: Greg Bergé <berge.greg@gmail.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@gitbook/embed": minor
|
||||
"gitbook": patch
|
||||
---
|
||||
|
||||
Docs Embed: Make trademark optional
|
||||
@@ -269,6 +269,19 @@ Notes:
|
||||
- The close button is rendered in the same sidebar area as tabs/actions.
|
||||
- If your UI hides that sidebar or doesn't render it, the button will not be visible.
|
||||
|
||||
### `trademark`
|
||||
|
||||
Available in: Standalone script, NPM package, React components
|
||||
|
||||
Display GitBook branding in the embed. Defaults to true.
|
||||
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `true`
|
||||
|
||||
```javascript
|
||||
trademark: true
|
||||
```
|
||||
|
||||
### `actions`
|
||||
|
||||
Available in: Standalone script, NPM package, React components
|
||||
|
||||
@@ -69,6 +69,7 @@ export function createGitBookFrame(iframe: HTMLIFrameElement): GitBookFrameClien
|
||||
greeting: { title: '', subtitle: '' },
|
||||
suggestions: [],
|
||||
tools: [],
|
||||
trademark: true,
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -68,6 +68,11 @@ export type GitBookEmbeddableConfiguration = {
|
||||
/** Tools to be provided to the assistant. */
|
||||
tools: GitBookToolDefinition[];
|
||||
|
||||
/**
|
||||
* Display GitBook branding in the embed.
|
||||
*/
|
||||
trademark?: boolean;
|
||||
|
||||
/**
|
||||
* Display a close button inside the assistant.
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,7 @@ export function GitBookFrame(props: GitBookFrameProps) {
|
||||
suggestions = [],
|
||||
tools = [],
|
||||
tabs = ['assistant', 'docs'],
|
||||
trademark = true,
|
||||
closeButton = false,
|
||||
} = props;
|
||||
|
||||
@@ -48,8 +49,9 @@ export function GitBookFrame(props: GitBookFrameProps) {
|
||||
suggestions,
|
||||
tools,
|
||||
closeButton,
|
||||
trademark,
|
||||
});
|
||||
}, [gitbookFrame, actions, greeting, suggestions, tools, tabs, closeButton]);
|
||||
}, [gitbookFrame, actions, greeting, suggestions, tools, tabs, closeButton, trademark]);
|
||||
|
||||
return (
|
||||
<iframe
|
||||
|
||||
@@ -65,6 +65,7 @@ let frameConfiguration: GitBookEmbeddableConfiguration & StandaloneConfiguration
|
||||
suggestions: [],
|
||||
tools: [],
|
||||
tabs: ['assistant', 'docs'],
|
||||
trademark: true,
|
||||
};
|
||||
|
||||
const widgetButton = document.createElement('button');
|
||||
@@ -156,6 +157,19 @@ const GitBook = (...args: StandaloneCalls) => {
|
||||
break;
|
||||
case 'configure': {
|
||||
const settings = args[1];
|
||||
|
||||
// If trademark is disabled, change the (branded) icon to the sparkle icon
|
||||
if (
|
||||
settings.trademark === false &&
|
||||
!settings.button?.icon &&
|
||||
frameConfiguration.button.icon === 'assistant'
|
||||
) {
|
||||
settings.button = {
|
||||
label: frameConfiguration.button.label,
|
||||
icon: 'sparkle',
|
||||
};
|
||||
}
|
||||
|
||||
frameConfiguration = {
|
||||
...frameConfiguration,
|
||||
...settings,
|
||||
|
||||
@@ -111,6 +111,7 @@ export function AIChat() {
|
||||
chatController={chatController}
|
||||
chat={chat}
|
||||
suggestions={config.suggestions}
|
||||
trademark={config.trademark}
|
||||
/>
|
||||
</EmbeddableFrameBody>
|
||||
</EmbeddableFrameMain>
|
||||
@@ -199,13 +200,13 @@ export function AIChatBody(props: {
|
||||
chat: AIChatState;
|
||||
welcomeMessage?: string;
|
||||
suggestions?: string[];
|
||||
trademark?: boolean;
|
||||
greeting?: {
|
||||
title: string;
|
||||
subtitle: string;
|
||||
};
|
||||
}) {
|
||||
const { chatController, chat, suggestions, greeting } = props;
|
||||
const { trademark } = useAI().config;
|
||||
const { chatController, chat, suggestions, greeting, trademark } = props;
|
||||
|
||||
const language = useLanguage();
|
||||
const now = useNow(60 * 60 * 1000); // Refresh every hour for greeting
|
||||
|
||||
@@ -41,9 +41,9 @@ type EmbeddableAIChatProps = {
|
||||
export function EmbeddableAIChat(props: EmbeddableAIChatProps) {
|
||||
const { baseURL, siteTitle } = props;
|
||||
const chat = useAIChatState();
|
||||
const { config } = useAI();
|
||||
const { config: siteConfig } = useAI();
|
||||
const chatController = useAIChatController();
|
||||
const configuration = useEmbeddableConfiguration();
|
||||
const embedConfig = useEmbeddableConfiguration();
|
||||
const language = useLanguage();
|
||||
|
||||
React.useEffect(() => {
|
||||
@@ -65,7 +65,8 @@ export function EmbeddableAIChat(props: EmbeddableAIChatProps) {
|
||||
}, [trackEvent]);
|
||||
|
||||
const tabsRef = React.useRef<HTMLDivElement>(null);
|
||||
const hasDocsTab = configuration.tabs.includes('docs');
|
||||
const hasDocsTab = embedConfig.tabs.includes('docs');
|
||||
const trademark = siteConfig.trademark && (embedConfig.trademark ?? true);
|
||||
const currentLinkContext = use(LinkContext);
|
||||
const linkContext: LinkContextType = useMemo(
|
||||
() =>
|
||||
@@ -95,14 +96,11 @@ export function EmbeddableAIChat(props: EmbeddableAIChatProps) {
|
||||
<EmbeddableFrameMain data-testid="ai-chat">
|
||||
<EmbeddableFrameHeader>
|
||||
{!tabsRef.current ? (
|
||||
<AIChatDynamicIcon
|
||||
className="animate-blur-in-slow"
|
||||
trademark={config.trademark}
|
||||
/>
|
||||
<AIChatDynamicIcon className="animate-blur-in-slow" trademark={trademark} />
|
||||
) : null}
|
||||
<EmbeddableFrameHeaderMain>
|
||||
<EmbeddableFrameTitle>
|
||||
{getAIChatName(language, config.trademark)}
|
||||
{getAIChatName(language, trademark)}
|
||||
</EmbeddableFrameTitle>
|
||||
<AIChatSubtitle chat={chat} />
|
||||
</EmbeddableFrameHeaderMain>
|
||||
@@ -115,8 +113,9 @@ export function EmbeddableAIChat(props: EmbeddableAIChatProps) {
|
||||
<AIChatBody
|
||||
chatController={chatController}
|
||||
chat={chat}
|
||||
suggestions={configuration.suggestions}
|
||||
greeting={configuration.greeting}
|
||||
suggestions={embedConfig.suggestions}
|
||||
greeting={embedConfig.greeting}
|
||||
trademark={trademark}
|
||||
/>
|
||||
</LinkContext>
|
||||
</EmbeddableFrameBody>
|
||||
|
||||
@@ -17,6 +17,7 @@ const embeddableConfiguration = createStore<GitBookEmbeddableConfiguration>(() =
|
||||
greeting: { title: '', subtitle: '' },
|
||||
suggestions: [],
|
||||
tools: [],
|
||||
trademark: true,
|
||||
}));
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: expected
|
||||
|
||||
@@ -12,6 +12,7 @@ import { SpaceLayoutServerContext } from '../SpaceLayout';
|
||||
import { Trademark } from '../TableOfContents/Trademark';
|
||||
import { NavigationLoader } from '../primitives/NavigationLoader';
|
||||
import { EmbeddableIframeAPI } from './EmbeddableIframeAPI';
|
||||
import { IfEmbeddableTrademark } from './EmbeddableTrademark';
|
||||
|
||||
type EmbeddableRootLayoutProps = {
|
||||
context: GitBookSiteContext;
|
||||
@@ -58,11 +59,13 @@ export async function EmbeddableRootLayout({
|
||||
<div className="fixed inset-0 flex flex-col">
|
||||
{children}
|
||||
{context.customization.trademark.enabled ? (
|
||||
<Trademark
|
||||
className="rounded-none! border-x-0 border-t border-b-0 bg-tint-solid/1 depth-flat:bg-tint-solid/1 px-4 py-2.5 text-tint/8"
|
||||
context={context}
|
||||
placement={SiteInsightsTrademarkPlacement.Embed}
|
||||
/>
|
||||
<IfEmbeddableTrademark>
|
||||
<Trademark
|
||||
className="rounded-none! border-x-0 border-t border-b-0 bg-tint-solid/1 depth-flat:bg-tint-solid/1 px-4 py-2.5 text-tint/8"
|
||||
context={context}
|
||||
placement={SiteInsightsTrademarkPlacement.Embed}
|
||||
/>
|
||||
</IfEmbeddableTrademark>
|
||||
) : null}
|
||||
</div>
|
||||
<EmbeddableIframeAPI
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
'use client';
|
||||
|
||||
import type React from 'react';
|
||||
import { useEmbeddableConfiguration } from './EmbeddableIframeAPI';
|
||||
|
||||
export function IfEmbeddableTrademark(props: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const { children } = props;
|
||||
const embedTrademarkEnabled = useEmbeddableConfiguration((state) => state.trademark ?? true);
|
||||
|
||||
return embedTrademarkEnabled ? children : null;
|
||||
}
|
||||
Reference in New Issue
Block a user