Skip to content

POC: Ask AI button and Kapa widget#108

Draft
czechian wants to merge 1 commit into
masterfrom
poc/ask-ai-integration
Draft

POC: Ask AI button and Kapa widget#108
czechian wants to merge 1 commit into
masterfrom
poc/ask-ai-integration

Conversation

@czechian

@czechian czechian commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Proof of concept for an AI assistant entry point in the docs theme (footer AI provider links were split out into their own PR):

  • Navbar "Ask AI" button (layouts/partials/ask-ai-button.html) — opens the Kapa AI widget via its open-kapa-widget override class.
  • Kapa widget loader (layouts/partials/ask-ai-widget.html, included from the body-end hook) — async widget.kapa.ai bundle; Kapa's own launcher stays hidden (data-button-hide), Cmd+K opens the modal, colors/logo/fonts overridable via params.askAI.* with GoodData-branded defaults.

Everything is config-gated: sites without params.askAI.websiteId get no button and no Kapa script.

[params.askAI]
  websiteId   = "..."   # required to enable the button + widget
  projectName = "GoodData"
  # projectColor, projectLogo, modalTitleColor, ... optional overrides

Verification

Built cleanly with Hugo 0.119 (current production version); the Kapa script is correctly absent while websiteId is unset in the theme's demo config.

Notes

  • Consumer doc sites opt in by setting params.askAI.websiteId after picking this theme version up.
  • The footer rework with AI provider links now lives in its own POC PR.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: a proof-of-concept adding an Ask AI button and Kapa widget.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
layouts/partials/footer.html (2)

110-110: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Potential ID collision between ai-buttons and footer-buttons.

Both the ai-buttons template (line 110: id="footer-btn-{{ lower .label }}") and the footer-buttons template (line 90: "idPrefix" "footer-btn-") use the footer-btn- ID prefix. If any social button text lowercases to a provider label (e.g., "ChatGPT"), the IDs will collide. Consider using a distinct prefix for AI provider buttons, such as footer-ai-btn-.

♻️ Suggested fix
-        <a class="gd-footer-buttons-item-icon-button" href="{{ printf "%s%s" .base (urlquery $query) | safeURL }}" id="footer-btn-{{ lower .label }}" aria-label="{{ .label }}" target="_blank" rel="noreferrer noopener">
+        <a class="gd-footer-buttons-item-icon-button" href="{{ printf "%s%s" .base (urlquery $query) | safeURL }}" id="footer-ai-btn-{{ lower .label }}" aria-label="{{ .label }}" target="_blank" rel="noreferrer noopener">
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/partials/footer.html` at line 110, Change the id prefix in the AI
provider button anchor within the ai-buttons template from footer-btn- to a
distinct prefix such as footer-ai-btn-. Keep the label-based suffix unchanged,
and leave the footer-buttons IDs untouched.

99-124: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Trailing space inside the aria-label conditional in absolute-link.

Line 124 emits aria-label="{{ .ariaLabel }}" with a trailing space before {{ end }}. This is harmless in HTML but produces a stray space attribute separator. Consider removing the trailing space for cleaner output.

♻️ Suggested fix
-  <a href="{{ $url }}" class="{{ .class }}" id="{{ .idPrefix }}{{ $id }}" target="_blank" {{ if (isset . "ariaLabel") }}aria-label="{{ .ariaLabel }}" {{ end }}{{ if (isset . "rel") }}rel="{{ .rel }}"{{end}}>{{ $content }}</a>
+  <a href="{{ $url }}" class="{{ .class }}" id="{{ .idPrefix }}{{ $id }}" target="_blank"{{ if (isset . "ariaLabel") }} aria-label="{{ .ariaLabel }}"{{ end }}{{ if (isset . "rel") }} rel="{{ .rel }}"{{ end }}>{{ $content }}</a>
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/partials/footer.html` around lines 99 - 124, Remove the trailing
whitespace emitted by the ariaLabel conditional in the absolute-link template,
while preserving the conditional aria-label attribute and surrounding link
attributes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@layouts/partials/ask-ai-button.html`:
- Line 12: Remove the static aria-controls="kapa-modal-content" attribute from
the ask-AI button markup. Keep the dynamic handling in ask-ai-accessibility.js
unchanged so it adds the attribute when the modal appears and removes it when
the modal disappears.

In `@layouts/partials/footer.html`:
- Line 17: Move the ai-buttons template invocation outside the bannerLinks range
loop, or guard it to render only on the first iteration using the loop index.
Ensure the provider button group and its hardcoded IDs are rendered exactly once
while preserving all banner link rendering.

In `@layouts/partials/hooks/body-end.html`:
- Line 14: Add /js/ask-ai-accessibility.js to the body-end script includes in
layouts/partials/hooks/body-end.html alongside the existing ask-ai widget
partial, ensuring it loads after the widget so `#ask-ai-button` receives its
dynamic aria-expanded and aria-controls behavior.

---

Nitpick comments:
In `@layouts/partials/footer.html`:
- Line 110: Change the id prefix in the AI provider button anchor within the
ai-buttons template from footer-btn- to a distinct prefix such as
footer-ai-btn-. Keep the label-based suffix unchanged, and leave the
footer-buttons IDs untouched.
- Around line 99-124: Remove the trailing whitespace emitted by the ariaLabel
conditional in the absolute-link template, while preserving the conditional
aria-label attribute and surrounding link attributes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 848720cd-142c-4f94-93db-a2499570becc

📥 Commits

Reviewing files that changed from the base of the PR and between 3203cf0 and 83f8e66.

⛔ Files ignored due to path filters (6)
  • assets/icons/ai.svg is excluded by !**/*.svg
  • assets/icons/chatgpt.svg is excluded by !**/*.svg
  • assets/icons/claude.svg is excluded by !**/*.svg
  • assets/icons/gemini.svg is excluded by !**/*.svg
  • assets/icons/grok.svg is excluded by !**/*.svg
  • assets/icons/perplexity.svg is excluded by !**/*.svg
📒 Files selected for processing (7)
  • assets/scss/_styles_project.scss
  • assets/scss/ask-ai-button.scss
  • layouts/partials/ask-ai-button.html
  • layouts/partials/ask-ai-widget.html
  • layouts/partials/footer.html
  • layouts/partials/hooks/body-end.html
  • layouts/partials/navbar.html

class="gd-docs-header-nav__cta gd-docs-header-nav__secondary open-kapa-widget ask-ai-button"
aria-expanded="false"
aria-haspopup="dialog"
aria-controls="kapa-modal-content"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Remove static aria-controls — the controlled element doesn't exist on initial load.

aria-controls="kapa-modal-content" is set in the HTML, but the kapa-modal-content element lives inside the Kapa widget's shadow DOM and won't exist until the async script loads and the user opens the modal. The accessibility JS in static/js/ask-ai-accessibility.js already adds aria-controls when the modal appears and removes it when it disappears. The static value is redundant and incorrectly references a non-existent element on initial page load, which can confuse screen readers.

♿ Proposed fix
         aria-expanded="false"
         aria-haspopup="dialog"
-        aria-controls="kapa-modal-content"
         id="ask-ai-button"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
aria-controls="kapa-modal-content"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/partials/ask-ai-button.html` at line 12, Remove the static
aria-controls="kapa-modal-content" attribute from the ask-AI button markup. Keep
the dynamic handling in ask-ai-accessibility.js unchanged so it adds the
attribute when the modal appears and removes it when the modal disappears.

Comment thread layouts/partials/footer.html Outdated
{{ with $link.subtitle }}
<p class="c-p mt-lg-4 mb-1 mb-lg-3">{{ . }}</p>
{{ end }}
{{ template "ai-buttons" }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

ai-buttons template is rendered inside the bannerLinks range loop, causing duplicate IDs when multiple banner links exist.

{{ template "ai-buttons" }} at line 17 is inside {{ range $index, $link := $footer.footer.bannerLinks }}. The ai-buttons template (line 110) generates hardcoded IDs like footer-btn-chatgpt, footer-btn-claude, etc. If bannerLinks contains more than one item, these IDs — and the entire provider button group — will be duplicated in the DOM, producing invalid HTML and potential accessibility/JS issues.

Consider moving the ai-buttons call outside the range loop, or guarding it to render only once (e.g., {{ if eq $index 0 }}{{ template "ai-buttons" }}{{ end }}).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/partials/footer.html` at line 17, Move the ai-buttons template
invocation outside the bannerLinks range loop, or guard it to render only on the
first iteration using the loop index. Ensure the provider button group and its
hardcoded IDs are rendered exactly once while preserving all banner link
rendering.

<script src="/js/prism-accessibility.js"></script>
{{ $themeSwitcherJS := resources.Get "js/theme-switcher.js" | minify | fingerprint }}
<script src="{{ $themeSwitcherJS.RelPermalink }}" integrity="{{ $themeSwitcherJS.Data.integrity }}" defer></script>
{{ partial "ask-ai-widget.html" . }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for where ask-ai-accessibility.js is loaded in the codebase.
rg -n "ask-ai-accessibility" --type=html --type=md

Repository: gooddata/gooddata-docs-theme

Length of output: 166


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== references to ask-ai =="
rg -n --hidden --glob '!**/.git/**' "ask-ai-accessibility|ask-ai-button|ask-ai-widget" .

echo
echo "== relevant template files =="
git ls-files 'layouts/**' 'static/js/**' | rg 'body-end|ask-ai|hooks|partials|js'

echo
echo "== body-end template =="
sed -n '1,220p' layouts/partials/hooks/body-end.html

Repository: gooddata/gooddata-docs-theme

Length of output: 3405


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== ask-ai-widget partial =="
sed -n '1,220p' layouts/partials/ask-ai-widget.html

echo
echo "== custom-scripts partial =="
sed -n '1,220p' layouts/partials/custom-scripts.html

echo
echo "== any direct include of ask-ai-accessibility.js =="
rg -n "/js/ask-ai-accessibility\.js|ask-ai-accessibility\.js" layouts static assets

Repository: gooddata/gooddata-docs-theme

Length of output: 2308


Load /js/ask-ai-accessibility.js with the other body-end scripts.
layouts/partials/hooks/body-end.html includes the widget partial, but not the accessibility helper. Without it, #ask-ai-button won’t get the dynamic aria-expanded / aria-controls behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@layouts/partials/hooks/body-end.html` at line 14, Add
/js/ask-ai-accessibility.js to the body-end script includes in
layouts/partials/hooks/body-end.html alongside the existing ask-ai widget
partial, ensuring it loads after the widget so `#ask-ai-button` receives its
dynamic aria-expanded and aria-controls behavior.

Navbar gains an "Ask AI" button that opens the Kapa AI widget, loaded
asynchronously from the body-end hook. Both render only when
params.askAI.websiteId is configured; Kapa's own launcher stays hidden
and theming (colors, logo, fonts) is overridable via params.askAI.*
with GoodData-branded defaults. Cmd+K also opens the modal.
@czechian
czechian force-pushed the poc/ask-ai-integration branch from 1f52619 to d125983 Compare July 17, 2026 16:15
@czechian czechian changed the title POC: Ask AI button, Kapa widget, and footer AI provider links POC: Ask AI button and Kapa widget Jul 17, 2026
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.

1 participant