Skip to content

feat(docs): add Kapa.ai sidebar integration#1113

Open
jessiemongeon1 wants to merge 6 commits into
mainfrom
feat/docs-kapa-ai-integration
Open

feat(docs): add Kapa.ai sidebar integration#1113
jessiemongeon1 wants to merge 6 commits into
mainfrom
feat/docs-kapa-ai-integration

Conversation

@jessiemongeon1

@jessiemongeon1 jessiemongeon1 commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add Kapa.ai widget Script tag configured in sidebar mode with hidden default button
  • Add KapaWidget.tsx component with KapaSidebar (state detection) and KapaButton ("Ask SDK AI")
  • Add KapaButton to navbar via layout.config.tsx
  • Add CSS rules in global.css for 500px content shift, nav adjustment, and mobile responsiveness

Test plan

  • Run pnpm turbo build --filter=@mysten/docs to verify no build errors
  • Verify Kapa widget loads on the site (requires KAPA_API_KEY_SDK secret)
  • Click "Ask SDK AI" button in navbar — sidebar should open on the right
  • Verify content shifts left by 500px when sidebar is open
  • Verify sidebar goes full-screen on mobile (< 768px)

AI Assistance Notice

Please disclose the usage of AI. This is primarily to help inform reviewers of how careful they need to review PRs, and to keep track of AI usage across our team. Please fill this out accurately, and do not modify the content or heading for this section!

  • This PR was primarily written by AI.
  • I used AI for docs / tests, but manually wrote the source code.
  • I used AI to understand the problem space / repository.
  • I did not use AI for this PR.

🤖 Generated with Claude Code

Add AI-powered knowledge assistant (Kapa.ai) as a sidebar widget
to the SDK documentation site. Includes KapaWidget React component
with sidebar state detection, navbar trigger button, and CSS rules
for responsive content shifting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jessiemongeon1
jessiemongeon1 requested a review from a team as a code owner June 23, 2026 23:19
@jessiemongeon1
jessiemongeon1 had a problem deploying to sui-typescript-aws-kms-test-env June 23, 2026 23:20 — with GitHub Actions Failure
@vercel

vercel Bot commented Jun 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
sui-typescript-docs Ready Ready Preview, Comment Jul 6, 2026 6:00pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ 🦋 Changesets Warning: This PR has changes to public npm packages, but does not contain a changeset. You can create a changeset easily by running pnpm changeset in the root of the Sui repo, and following the prompts. If your change does not need a changeset (e.g. a documentation-only change), you can ignore this message. This warning will be removed when a changeset is added to this pull request.

Learn more about Changesets.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use Kapa default floating button instead of navbar injection
- Set data-launcher-button-image and data-modal-image for proper icons
- Rename modal title to "Ask Mysten Labs SDK AI"
- Add floating button CSS styles
- Revert layout.config.tsx to clean state

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add data-color-scheme-selector for automatic dark mode following
- Clean up unused KapaButton component and layout config import

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Kapa widget's built-in launcher button was overlapping with
the custom "Ask SDK AI" button since both were fixed to the
bottom-right corner. Setting data-button-hide to true hides the
native button while keeping the custom one.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@hayes-mysten

Copy link
Copy Markdown
Contributor

@clud-bot review

}

function hookKapa() {
if (!window.Kapa || !window.Kapa.open || window.Kapa.open === hookedRef) return;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this how they recommend building this out, this feels like a pretty hacky way to manage a sidebar

@clud-bot clud-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: COMMENT

Docs-only front-end change (Kapa.ai sidebar). Nothing exploitable or data-losing — the site is fine to run. But the sidebar-detection approach has several concrete UX/robustness defects worth fixing before merge. Left inline comments; summary below.

Major

  • The 300ms elementFromPoint poll overwrites the state set by the hooked open()/close(), so every open/close flickers as the sidebar animates in.
  • The whole detection heuristic looks unnecessary and fragile: Kapa already renders in data-view-mode="sidebar", and getElementById('nd-docs-layout') resolves to null (that id doesn't exist in the repo), so a fixed/sticky element outside <main> can produce a permanent false positive. Prefer Kapa's official view-mode / state callbacks over DOM probing — this is the "hacky" concern confirmed.

Minor

  • Unused useState import (oxlint warning, doesn't fail CI).
  • Monkeypatch on window.Kapa.open/close is never restored; a remount double-wraps.
  • global.css hardcodes a 500px shift not tied to the actual sidebar width.
  • The global nav selector is over-broad (hits every <nav>).
  • Launcher button is a silent no-op if clicked before the async Kapa script loads.

Cleared (not issues): hardcoded data-website-id is a public client id (not a secret), missing changeset is allowed for docs-only, and the 'use client'/SSR handling is clean.

return true;
}

const interval = setInterval(() => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Polling overwrites the monkeypatch state, causing flicker. Every 300ms this interval recomputes kapaOpen purely from the elementFromPoint guess, discarding what the hooked open()/close() just set. On click, open() sets kapaOpen=true + adds the class, but Kapa's sidebar animates in over a few hundred ms — the next tick probes the right-middle point before the sidebar occupies it, reads visible=false, flips the class off (body snaps back, floating button reappears), then re-adds it next tick. Result is a flicker on every open/close.

hookedRef = window.Kapa.open;
}

function isSidebarVisible() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This detection heuristic is likely unnecessary and fragile. The <Script> already sets data-view-mode="sidebar" (layout.tsx), so Kapa natively renders a sidebar — this custom elementFromPoint polling reinvents that. Also, getElementById('nd-docs-layout') returns null (that id doesn't exist anywhere in the repo and Fumadocs doesn't emit it), so containment falls back solely to querySelector('main'). Any fixed/sticky element at (innerWidth-50, innerHeight/2) outside <main> (e.g. Fumadocs' right-hand TOC <aside>) yields a permanent false positive, leaving the body shifted 500px with the button hidden. Prefer Kapa's official view-mode / state callbacks over DOM-probing.


'use client';

import { useEffect, useState } from 'react';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused useState import — oxlint's no-unused-vars flags it (warning only, so CI still passes). Remove it.

document.documentElement.classList.toggle(OPEN_CLASS, kapaOpen);
}

function hookKapa() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Monkeypatch is never restored; remount double-wraps. Cleanup only clears the interval — window.Kapa.open/close stay wrapped. React StrictMode (dev) or any remount gets a fresh hookedRef=null and re-wraps the already-wrapped functions. Harmless in today's single-mount layout, latent leak otherwise.


export function KapaButton() {
return (
<button type="button" onClick={() => window.Kapa?.open()} className="kapa-floating-btn">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Button is a silent no-op before the async script loads: window.Kapa?.open() does nothing if clicked before afterInteractive defines window.Kapa. Consider a disabled/loading state.

width: calc(100vw - 500px) !important;
overflow-x: hidden;
transition: width 0.3s ease;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded 500px shift isn't tied to Kapa's actual sidebar width. calc(100vw - 500px) (and the nav right: 500px) assume the widget is exactly 500px — if Kapa's sidebar width differs now or later, content overlaps or leaves a gap.

html.kapa-sidebar-open nav {
right: 500px !important;
overflow: hidden;
transition: right 0.3s ease;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The global nav selector is over-broad — these rules target every <nav> (top navbar, left sidebar, TOC), not just the intended one, so any positioned nav shifts 500px when the class is active. Scope this to the specific nav.

@MystenLabs MystenLabs deleted a comment from clud-bot Bot Jul 6, 2026
@MystenLabs MystenLabs deleted a comment from clud-bot Bot Jul 6, 2026
@MystenLabs MystenLabs deleted a comment from clud-bot Bot Jul 6, 2026
@MystenLabs MystenLabs deleted a comment from clud-bot Bot Jul 6, 2026
@hayes-mysten

Copy link
Copy Markdown
Contributor

@clud-bot can you update this to use the proper react bindings rather than trying to hack around their injected script?

@clud-bot

clud-bot Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Something went wrong:

Agent stream error: An error occurred.

1 similar comment
@clud-bot

clud-bot Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Something went wrong:

Agent stream error: An error occurred.

@clud-bot

clud-bot Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Something went wrong:

Agent stream error: An error occurred.

1 similar comment
@clud-bot

clud-bot Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Something went wrong:

Agent stream error: An error occurred.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants