Skip to content

Commit 226bc98

Browse files
gmarullclaude
authored andcommitted
doc: integrate Kapa.ai search widget
Replace the default Sphinx search with the Kapa.ai widget, triggered by clicking the existing header search input or pressing Cmd/Ctrl+K. The widget is wired up via a new add_kapa_search() helper in doc/_utils/utils.py, called from each docset's setup(). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
1 parent 6867339 commit 226bc98

11 files changed

Lines changed: 77 additions & 0 deletions

File tree

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
/cmake/ @nrfconnect/ncs-co-build-system
6666

6767
# All doc related files
68+
/doc/_static/ @nrfconnect/ncs-co-doc @nrfconnect/ncs-doc-leads
6869
/doc/_zoomin/ @nrfconnect/ncs-co-doc @nrfconnect/ncs-doc-leads
6970
/doc/_doxygen/ @nrfconnect/ncs-co-doc @nrfconnect/ncs-doc-leads
7071
/doc/_extensions/ @nrfconnect/ncs-co-doc @nrfconnect/ncs-doc-leads

doc/_static/css/kapa-widget.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/* Copyright (c) 2026 Nordic Semiconductor ASA
2+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
3+
*/
4+
5+
input.ncs-search-input {
6+
cursor: pointer !important;
7+
caret-color: transparent !important;
8+
}

doc/_static/js/kapa-widget.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Copyright (c) 2026 Nordic Semiconductor ASA
2+
// SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
3+
4+
document.addEventListener("DOMContentLoaded", function () {
5+
var script = document.createElement("script");
6+
script.src = "https://widget.kapa.ai/kapa-widget.bundle.js";
7+
script.setAttribute("data-website-id", "a5232253-05bb-40ed-8e4e-841cdff33180");
8+
script.setAttribute("data-project-name", "Nordic Semiconductor");
9+
script.setAttribute("data-project-color", "#00A2C6");
10+
script.setAttribute("data-project-logo", "https://nos-p-001.sitecorecontenthub.cloud/api/public/content/4ccdb34064ca4d968a46f4920d037adc?v=637062d8");
11+
script.setAttribute("data-modal-title", "Nordic Semiconductor AI");
12+
script.setAttribute("data-modal-disclaimer", "Answers are generated by Nordic Semiconductor's AI chatbot and may not be fully accurate. The service is provided as is, without any warranties regarding completeness, reliability or accuracy. User discretion is advised. Nordic Semiconductor disclaim all warranties and shall not be liable for any damages arising from the use of its AI systems.");
13+
script.setAttribute("data-modal-example-questions-title", "Example Questions");
14+
script.setAttribute("data-modal-example-questions", "Give me a list of compatibility matrices.,Where can I find the nRF54L15 data sheet?");
15+
script.setAttribute("data-modal-ask-ai-input-placeholder", "Ask a question about our products and services.");
16+
script.setAttribute("data-button-bg-color", "transparent");
17+
script.setAttribute("data-button-hover-bg-color", "transparent");
18+
script.setAttribute("data-button-border", "none");
19+
script.setAttribute("data-button-box-shadow", "none");
20+
script.setAttribute("data-button-text", " ");
21+
script.setAttribute("data-button-image-height", "3.125rem");
22+
script.setAttribute("data-button-image-width", "3.125rem");
23+
script.setAttribute("data-button-hover-animation-enabled", "false");
24+
script.setAttribute("data-user-analytics-fingerprint-enabled", "true");
25+
script.setAttribute("data-modal-open-on-command-k", "true");
26+
script.setAttribute("data-search-mode-enabled", "true");
27+
script.async = true;
28+
29+
// Wire the Sphinx search bar to open the Kapa modal on the "Search" tab.
30+
// The bottom-right floating button keeps its default behavior (Ask AI tab).
31+
// Only the "click" event is bound: binding "focus" or "keydown" causes the
32+
// modal to immediately reopen when dismissed, because closing it returns
33+
// focus to the search input. The input is set to readonly so users cannot
34+
// type into it directly; all input happens inside the Kapa modal.
35+
script.onload = function () {
36+
var openSearch = function (e) {
37+
e.preventDefault();
38+
if (window.Kapa && typeof window.Kapa.open === "function") {
39+
window.Kapa.open({ mode: "search" });
40+
}
41+
};
42+
43+
document.querySelectorAll(".ncs-search-input").forEach(function (el) {
44+
el.setAttribute("readonly", "readonly");
45+
el.addEventListener("click", openSearch);
46+
});
47+
};
48+
49+
document.head.appendChild(script);
50+
});

doc/_utils/utils.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,17 @@ def add_google_analytics(app: Sphinx, options: dict) -> None:
140140
options["add_gtm"] = True
141141
options["gtm_id"] = "GTM-WF4CVFX"
142142

143+
def add_kapa_search(app: Sphinx) -> None:
144+
"""Add Kapa.ai search widget to a docset.
145+
146+
Args:
147+
app: Sphinx instance.
148+
"""
149+
150+
app.add_css_file("css/kapa-widget.css")
151+
app.add_js_file("js/kapa-widget.js")
152+
153+
143154
def add_announcement_banner(options: dict) -> None:
144155
"""Add an announcement banner to the top of the page.
145156
Args:

doc/kconfig/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,5 @@ def setup(app):
7878
app.add_css_file("css/kconfig.css")
7979

8080
utils.add_google_analytics(app, html_theme_options)
81+
utils.add_kapa_search(app)
8182
utils.add_announcement_banner(html_theme_options)

doc/matter/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,5 @@ def setup(app):
7979
app.add_css_file("css/matter.css")
8080

8181
utils.add_google_analytics(app, html_theme_options)
82+
utils.add_kapa_search(app)
8283
utils.add_announcement_banner(html_theme_options)

doc/mcuboot/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,5 @@
9494

9595
def setup(app):
9696
utils.add_google_analytics(app, html_theme_options)
97+
utils.add_kapa_search(app)
9798
utils.add_announcement_banner(html_theme_options)

doc/nrf/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,4 +238,5 @@ def setup(app):
238238
app.add_css_file("css/nrf.css")
239239

240240
utils.add_google_analytics(app, html_theme_options)
241+
utils.add_kapa_search(app)
241242
utils.add_announcement_banner(html_theme_options)

doc/nrfxlib/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,5 @@ def setup(app):
119119
app.add_css_file("css/nrfxlib.css")
120120

121121
utils.add_google_analytics(app, html_theme_options)
122+
utils.add_kapa_search(app)
122123
utils.add_announcement_banner(html_theme_options)

doc/tfm/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,5 @@ def setup(app):
100100
app.add_css_file("css/tfm.css")
101101

102102
utils.add_google_analytics(app, html_theme_options)
103+
utils.add_kapa_search(app)
103104
utils.add_announcement_banner(html_theme_options)

0 commit comments

Comments
 (0)