Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
2382e63
Move to (content)
SamyPesse Aug 17, 2025
f76d01b
Start
SamyPesse Aug 17, 2025
b20f454
Render the assistant
SamyPesse Aug 17, 2025
8279d2d
Improve styling
SamyPesse Aug 17, 2025
a065ddb
Start better components
SamyPesse Aug 17, 2025
70ec1b5
Start shape for client
SamyPesse Aug 17, 2025
af56253
Continue
SamyPesse Aug 18, 2025
8ec79af
Continue
SamyPesse Aug 18, 2025
1b60b2a
push more example
SamyPesse Aug 18, 2025
23a2280
Build bundle and copy it
SamyPesse Aug 18, 2025
0f780f4
Expose script
SamyPesse Aug 18, 2025
4d6da38
Add link for demo
SamyPesse Aug 18, 2025
332671a
Wrap in the proper client context
SamyPesse Aug 18, 2025
7c7020a
Remove nonce
SamyPesse Aug 18, 2025
ec6f24b
Remove useless script
SamyPesse Aug 18, 2025
09ca4ab
Move nuqs adapter
SamyPesse Aug 19, 2025
27899bc
Start rendering embedded pages
SamyPesse Aug 19, 2025
ccbfb5c
Start changing API
SamyPesse Aug 19, 2025
b92e8f4
Start iframe API
SamyPesse Aug 19, 2025
a95b6bf
Merge branch 'main' into embed-assistant
SamyPesse Aug 19, 2025
33e3970
Continue
SamyPesse Aug 19, 2025
0882c10
Fix basic
SamyPesse Aug 20, 2025
38a0c98
Updat next and use turbopack
SamyPesse Aug 20, 2025
90fa0ca
Continue
SamyPesse Aug 20, 2025
c483bbc
Properly handle links
SamyPesse Aug 20, 2025
bde9050
Merge branch 'main' into embed-assistant
zenoachtig Aug 20, 2025
9f4b7fb
Start showing icon
SamyPesse Aug 20, 2025
94acf21
Improve style
SamyPesse Aug 20, 2025
d6d4a48
Remove turbopack
zenoachtig Aug 21, 2025
613bc1f
Change to fragment
zenoachtig Aug 21, 2025
fd4bc08
Merge branch 'main' into embed-assistant
zenoachtig Aug 21, 2025
4cb9b9b
Button styling & animation
zenoachtig Aug 21, 2025
cc0a09d
Add translucency to button
zenoachtig Aug 21, 2025
82ba4a8
Add intro animation
zenoachtig Aug 21, 2025
e3ad0a0
Merge branch 'main' into embed-assistant
SamyPesse Aug 21, 2025
b8c57ae
Update icons
zenoachtig Aug 21, 2025
dc69aa9
Structure and prepare for dynamic route
SamyPesse Aug 21, 2025
6e2f2cb
Fix one
SamyPesse Aug 21, 2025
6af903c
Add dynamic route
SamyPesse Aug 21, 2025
4440a6a
Merge branch 'embed-assistant' of https://github.com/GitbookIO/gitboo…
SamyPesse Aug 21, 2025
6350554
Remove test
SamyPesse Aug 21, 2025
a24a4a3
Fix build
SamyPesse Aug 21, 2025
2af1ab7
Revert esbuild
SamyPesse Aug 21, 2025
92b8237
Try something else for playwright
SamyPesse Aug 21, 2025
430fcf3
Try without install
SamyPesse Aug 21, 2025
f512fee
Remove setup steps
SamyPesse Aug 21, 2025
a6535b5
Comment
SamyPesse Aug 21, 2025
dd77b81
Comment more
SamyPesse Aug 21, 2025
f24dd07
Use chromium name
SamyPesse Aug 21, 2025
1a18f39
Cleanup
SamyPesse Aug 21, 2025
97289c1
Fix test
SamyPesse Aug 21, 2025
1f3945c
Changesets
SamyPesse Aug 21, 2025
160f7f7
Fix test
SamyPesse Aug 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/angry-melons-sparkle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@gitbook/embed": patch
---

Initial version of the embed SDK.
5 changes: 5 additions & 0 deletions .changeset/sweet-garlics-do.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gitbook": minor
---

Start routes for embeddable version of the assistant and docs pages.
37 changes: 0 additions & 37 deletions .github/actions/setup-playwright/action.yml

This file was deleted.

16 changes: 8 additions & 8 deletions .github/workflows/deploy-preview.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ jobs:
uses: ./.github/composite/setup-bun
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Setup Playwright
uses: ./.github/actions/setup-playwright
env:
PUPPETEER_SKIP_DOWNLOAD: 1
- name: Run Playwright tests
run: bun e2e
env:
Expand All @@ -131,8 +131,8 @@ jobs:
uses: ./.github/composite/setup-bun
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Setup Playwright
uses: ./.github/actions/setup-playwright
env:
PUPPETEER_SKIP_DOWNLOAD: 1
- name: Run Playwright tests
run: bun e2e
env:
Expand All @@ -152,8 +152,8 @@ jobs:
uses: ./.github/composite/setup-bun
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Setup Playwright
uses: ./.github/actions/setup-playwright
env:
PUPPETEER_SKIP_DOWNLOAD: 1
- name: Run Playwright tests
run: bun e2e-customers
env:
Expand All @@ -173,8 +173,8 @@ jobs:
uses: ./.github/composite/setup-bun
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Setup Playwright
uses: ./.github/actions/setup-playwright
env:
PUPPETEER_SKIP_DOWNLOAD: 1
- name: Run Playwright tests
run: bun e2e-customers
env:
Expand Down
102 changes: 60 additions & 42 deletions bun.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"workspaces": {
"packages": ["packages/*"],
"catalog": {
"@gitbook/api": "^0.136.0"
"@gitbook/api": "^0.136.0",
"bidc": "^0.0.2"
}
},
"patchedDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions packages/embed/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dist/
standalone/
49 changes: 49 additions & 0 deletions packages/embed/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# `@gitbook/embed`

Embed the GitBook Docs Assistant in your product or website.

# Usage

## As a script from your docs site

All GitBook docs site includes a script to easily embed the docs assistant as a widget on your website.

The script is served at `https://docs.company.com/~gitbook/embed/script.js`.

You can find the embed script from your docs site settings, or you can copy the following and replace the `docs.company.com` by your docs site hostname.

```html
<script src="https://docs.company.com/~gitbook/embed/script.js"></script>
<script>
window.GitBook('show');
</script>
```

## As a package from NPM

Install the package: `npm install @gitbook/embed` and import it in your web application:

```tsx
import { createGitBook } from '@gitbook/embed';

const gitbook = createGitBook({
siteURL: 'https://docs.company.com'
});

const iframe = document.createElement('iframe');
iframe.src = gitbook.getFrameURL();

const frame = gitbook.createFrame(iframe);
```

## As React components

After installing the NPM package, you can import prebuilt React components:

```tsx
import { GitBookProvider, GitBookAssistantFrame } from '@gitbook/embed/react';

<GitBookProvider siteURL="https://docs.company.com">
<GitBookAssistantFrame />
</GitBookProvider>
```
31 changes: 31 additions & 0 deletions packages/embed/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "@gitbook/embed",
"description": "Embeddable components for GitBook",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js",
"standalone": "./dist/standalone/index.js",
"react": "./dist/react/index.js"
}
},
"version": "0.0.0",
"dependencies": {
"@gitbook/api": "catalog:",
"@gitbook/icons": "workspace:",
"bidc": "catalog:"
},
"peerDependencies": {
"react": "^18.0.0"
},
"devDependencies": {
"typescript": "^5.5.3",
"react": "^19.0.0"
},
"scripts": {
"build": "tsc && bun build src/standalone/index.ts --bundle --minify --outdir=standalone",
"typecheck": "tsc --noEmit"
},
"files": ["dist", "README.md", "CHANGELOG.md", "standalone"]
}
61 changes: 61 additions & 0 deletions packages/embed/src/client/createGitBook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { type GitBookFrameClient, createGitBookFrame } from './createGitBookFrame';

export type CreateGitBookOptions = {
/**
* URL of the GitBook site to embed.
*/
siteURL: string;
};

export type GetFrameURLOptions = {
/**
* Authentication to use for the frame.
*/
visitor?: {
/**
* Signed JWT token for Adaptive Content or Visitor Authentication to use.
*/
token?: string;

/**
* Unsigned claims to pass to the frame.
* You can use these claims in dynamic expressions using `visitor.claims.unsigned.<claim-name>`.
*/
unsignedClaims?: Record<string, unknown>;
};
};

export type GitBookClient = {
/**
* Get the URL for a GitBook frame.
*/
getFrameURL: (options: GetFrameURLOptions) => string;
/**
* Create a new GitBook frame.
*/
createFrame: (iframe: HTMLIFrameElement) => GitBookFrameClient;
};

export function createGitBook(options: CreateGitBookOptions) {
const client: GitBookClient = {
getFrameURL: (frameOptions) => {
const url = new URL(options.siteURL);
url.pathname = `${url.pathname.endsWith('/') ? url.pathname : `${url.pathname}/`}~gitbook/embed/assistant`;

if (frameOptions.visitor?.token) {
url.searchParams.set('token', frameOptions.visitor.token);
}

if (frameOptions.visitor?.unsignedClaims) {
Object.entries(frameOptions.visitor.unsignedClaims).forEach(([key, value]) => {
url.searchParams.set(`visitor.${key}`, String(value));
});
}

return url.toString();
},
createFrame: (iframe) => createGitBookFrame(iframe),
};

return client;
}
93 changes: 93 additions & 0 deletions packages/embed/src/client/createGitBookFrame.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { createChannel } from 'bidc';
import type {
FrameToParentMessage,
GitBookPlaceholderSettings,
GitBookToolDefinition,
ParentToFrameMessage,
} from './protocol';

export type GitBookFrameClient = {
/**
* Navigate to a page by its path.
*/
navigateToPage: (path: string) => void;

/**
* Navigate to the assistant.
*/
navigateToAssistant: () => void;

/**
* Post a message to the chat.
*/
postUserMessage: (message: string) => void;

/**
* Register a custom tool.
*/
registerTool: (tool: GitBookToolDefinition) => void;

/**
* Clear the chat.
*/
clearChat: () => void;

/**
* Set the placeholder settings.
*/
setPlaceholder: (placeholder: GitBookPlaceholderSettings) => void;

/**
* Register an event listener.
*/
on: (event: string, listener: (...args: any[]) => void) => () => void;
};

/**
* Create a client to communicate with the GitBook Assistant frame.
*/
export function createGitBookFrame(iframe: HTMLIFrameElement): GitBookFrameClient {
if (!iframe.contentWindow) {
throw new Error('Iframe must have a content window');
}
const channel = createChannel(iframe.contentWindow);

channel.receive((message: FrameToParentMessage) => {
if (message.type === 'close') {
const listeners = events.get('close') || [];
if (listeners) {
listeners.forEach((listener) => listener());
}
}
});

const sendToFrame = (message: ParentToFrameMessage) => {
channel.send(message);
};

const events = new Map<string, Array<(...args: any[]) => void>>();

return {
navigateToPage: (pagePath) => {
sendToFrame({ type: 'navigateToPage', pagePath });
},
navigateToAssistant: () => {
sendToFrame({ type: 'navigateToAssistant' });
},
postUserMessage: (message) => sendToFrame({ type: 'postUserMessage', message }),
registerTool: (tool) => sendToFrame({ type: 'registerTool', tool }),
clearChat: () => sendToFrame({ type: 'clearChat' }),
setPlaceholder: (settings) => sendToFrame({ type: 'setPlaceholder', settings }),
on: (event, listener) => {
const listeners = events.get(event) || [];
listeners.push(listener);
events.set(event, listeners);
return () => {
events.set(
event,
listeners.filter((l) => l !== listener)
);
};
},
};
}
3 changes: 3 additions & 0 deletions packages/embed/src/client/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './createGitBook';
export * from './createGitBookFrame';
export * from './protocol';
Loading