diff --git a/docs-config.ts b/docs-config.ts
index c031e5bc9..2eec1892a 100644
--- a/docs-config.ts
+++ b/docs-config.ts
@@ -5,11 +5,19 @@ export default {
announcement: {
text: "Take the [Prometheus User Survey (Edition 03.2026)](https://forms.gle/uuEsawKm7u9wCT4T8) and help the community prioritize future development!",
- mobileText: "[Prometheus User Survey (Edition 03.2026)](https://forms.gle/uuEsawKm7u9wCT4T8)",
+ mobileText:
+ "[Prometheus User Survey (Edition 03.2026)](https://forms.gle/uuEsawKm7u9wCT4T8)",
startDate: "2026-03-24",
endDate: "2026-04-07",
},
+ kapa: {
+ websiteId: "80cbacc9-0b84-48aa-bfb8-0002270176bf",
+ projectName: "Prometheus",
+ projectColor: "#D86444",
+ projectLogoPath: "/assets/prometheus-logo.svg",
+ },
+
// Docs to load from repo-local files.
localMarkdownSources: [
{
diff --git a/public/assets/prometheus-logo.svg b/public/assets/prometheus-logo.svg
new file mode 100644
index 000000000..c4788dab1
--- /dev/null
+++ b/public/assets/prometheus-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index d2dbe1d2e..3132eff56 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -21,6 +21,7 @@ import "@mantine/code-highlight/styles.layer.css";
import "@mantine/spotlight/styles.layer.css";
import "./globals.css";
import { Header } from "@/components/Header";
+import KapaWidget from "@/components/KapaWidget";
import {
ANNOUNCEMENT_HEIGHT_PX,
isAnnouncementActive,
@@ -53,8 +54,7 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
const activeAnnouncement =
- docsConfig.announcement &&
- isAnnouncementActive(docsConfig.announcement)
+ docsConfig.announcement && isAnnouncementActive(docsConfig.announcement)
? docsConfig.announcement
: undefined;
@@ -67,13 +67,16 @@ export default function RootLayout({
lang="en"
{...mantineHtmlProps}
className={`${interFont.variable} ${latoFont.variable}`}
- style={{ "--header-height": `${headerHeightPx}px` } as React.CSSProperties}
+ style={
+ { "--header-height": `${headerHeightPx}px` } as React.CSSProperties
+ }
>
+
diff --git a/src/components/Header.tsx b/src/components/Header.tsx
index 35efb233e..3723197d0 100644
--- a/src/components/Header.tsx
+++ b/src/components/Header.tsx
@@ -141,7 +141,7 @@ export const Header = ({
+ // so that the Kapa widget can detect theme changes. Kapa only watches
+ // class, data-theme, data-color-mode, and data-bs-theme.
+ useEffect(() => {
+ document.documentElement.setAttribute("data-theme", colorScheme);
+ }, [colorScheme]);
+
+ if (!docsConfig.kapa) {
+ return null;
+ }
+
+ const { websiteId, projectName, projectColor, projectLogoPath } =
+ docsConfig.kapa;
+ const projectLogoUrl = new URL(
+ projectLogoPath,
+ docsConfig.siteUrl,
+ ).toString();
+
+ return (
+
+ );
+}
diff --git a/src/components/SpotlightSearch.tsx b/src/components/SpotlightSearch.tsx
index d26a9400b..0754518cc 100644
--- a/src/components/SpotlightSearch.tsx
+++ b/src/components/SpotlightSearch.tsx
@@ -1,17 +1,25 @@
"use client";
-import { Spotlight } from "@mantine/spotlight";
-import { IconSearch } from "@tabler/icons-react";
+import { Spotlight, spotlight } from "@mantine/spotlight";
+import { IconSearch, IconSparkles } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
-import { Divider, Group, Highlight, Loader, Space } from "@mantine/core";
-import React, { useState, useEffect } from "react";
+import {
+ Button,
+ Divider,
+ Group,
+ Highlight,
+ Loader,
+ Space,
+} from "@mantine/core";
+import React, { useState, useEffect, useRef } from "react";
import { decode } from "html-entities";
-// Extend Window interface to include pagefind
+// Extend Window interface to include pagefind and Kapa
declare global {
interface Window {
/* eslint-disable @typescript-eslint/no-explicit-any */
pagefind: any;
+ Kapa: any;
}
}
@@ -127,6 +135,7 @@ type PagefindResult = {
export default function SpotlightSearch() {
const [activeQuery, setActiveQuery] = useState("");
const [results, setResults] = useState([]);
+ const queryRef = useRef("");
useEffect(() => {
async function loadPagefind() {
@@ -175,12 +184,24 @@ export default function SpotlightSearch() {
loadPagefind();
}, []);
+ const handleAskAI = () => {
+ const query = queryRef.current.trim();
+ spotlight.close();
+ // Small delay to let the Spotlight close animation finish before opening Kapa.
+ setTimeout(() => {
+ if (window.Kapa) {
+ window.Kapa.open({ mode: "ai", query, submit: query.length > 0 });
+ }
+ }, 100);
+ };
+
return (
{
+ queryRef.current = query;
const search = await window.pagefind.debouncedSearch(query);
if (search === null) {
// A more recent search call has been made, nothing to do.
@@ -190,10 +211,24 @@ export default function SpotlightSearch() {
setActiveQuery(query);
}}
>
- }
- />
+
+ }
+ style={{ flex: 1 }}
+ />
+ }
+ mr="xs"
+ fw={500}
+ style={{ flexShrink: 0 }}
+ >
+ Ask AI
+
+
{results.length > 0 ? (
results.map((result, idx) => (
diff --git a/src/docs-config-types.ts b/src/docs-config-types.ts
index 55aac1f22..9130c9caf 100644
--- a/src/docs-config-types.ts
+++ b/src/docs-config-types.ts
@@ -10,9 +10,17 @@ export type Announcement = {
endDate?: string;
};
+export type KapaConfig = {
+ websiteId: string;
+ projectName: string;
+ projectColor: string;
+ projectLogoPath: string;
+};
+
export type DocsConfig = {
siteUrl: string;
announcement?: Announcement;
+ kapa?: KapaConfig;
localMarkdownSources: LocalMarkdownSource[];
githubMarkdownSources: GithubMarkdownSource[];
ltsVersions: LTSConfig;