diff --git a/packages/playground/website/src/components/site-error-modal/site-error-modal.tsx b/packages/playground/website/src/components/site-error-modal/site-error-modal.tsx
index 1e0a23e77e..412e09a388 100644
--- a/packages/playground/website/src/components/site-error-modal/site-error-modal.tsx
+++ b/packages/playground/website/src/components/site-error-modal/site-error-modal.tsx
@@ -20,6 +20,7 @@ import type {
} from './types';
import { getSiteErrorView } from './get-site-error-view';
import type { SiteInfo } from '../../lib/state/redux/slice-sites';
+import { useKapaAI } from './use-kapa-ai';
export function SiteErrorModal({
error,
@@ -38,6 +39,7 @@ export function SiteErrorModal({
isSubmittingReport,
handleSubmitReport,
} = useErrorReporting(site);
+ const { isConfigured: isKapaAIConfigured, openWithQuery } = useKapaAI();
const helpers: PresentationHelpers = {
deleteSite: () => {
@@ -142,8 +144,16 @@ export function SiteErrorModal({
)}
- {view.actions.length || !view.isDeveloperError ? (
+ {view.actions.length || !view.isDeveloperError || detailText ? (
+ {isKapaAIConfigured && !isReporting && detailText && (
+
+ )}
{!view.isDeveloperError &&
!isReporting &&
!reportSubmitted ? (
diff --git a/packages/playground/website/src/components/site-error-modal/use-kapa-ai.ts b/packages/playground/website/src/components/site-error-modal/use-kapa-ai.ts
new file mode 100644
index 0000000000..3f9dc9b19f
--- /dev/null
+++ b/packages/playground/website/src/components/site-error-modal/use-kapa-ai.ts
@@ -0,0 +1,97 @@
+import { useEffect, useCallback, useState } from 'react';
+// @ts-ignore - Virtual module injected by Vite
+import { kapaWebsiteId } from 'virtual:kapa-ai-config';
+
+declare global {
+ interface Window {
+ Kapa?: {
+ open: (options?: {
+ mode?: 'ai' | 'search';
+ query?: string;
+ submit?: boolean;
+ }) => void;
+ close: () => void;
+ render: (options?: { onRender?: () => void }) => void;
+ unmount: () => void;
+ };
+ }
+}
+
+const KAPA_SCRIPT_ID = 'kapa-widget-script';
+
+export function useKapaAI() {
+ const [isLoaded, setIsLoaded] = useState(false);
+ const isConfigured = Boolean(kapaWebsiteId);
+
+ useEffect(() => {
+ if (!isConfigured) {
+ return;
+ }
+
+ // Check if script already exists
+ if (document.getElementById(KAPA_SCRIPT_ID)) {
+ if (window.Kapa) {
+ setIsLoaded(true);
+ }
+ return;
+ }
+
+ const script = document.createElement('script');
+ script.id = KAPA_SCRIPT_ID;
+ script.src = 'https://widget.kapa.ai/kapa-widget.bundle.js';
+ script.async = true;
+ script.setAttribute('data-website-id', kapaWebsiteId);
+ script.setAttribute('data-project-name', 'WordPress Playground');
+ script.setAttribute('data-project-color', '#3858e9');
+ script.setAttribute(
+ 'data-project-logo',
+ 'https://playground.wordpress.net/logo-square.png'
+ );
+ script.setAttribute('data-button-hide', 'true');
+
+ script.onload = () => {
+ const checkKapa = setInterval(() => {
+ if (window.Kapa) {
+ clearInterval(checkKapa);
+ setIsLoaded(true);
+ }
+ }, 100);
+
+ setTimeout(() => clearInterval(checkKapa), 5000);
+ };
+
+ document.body.appendChild(script);
+ }, [isConfigured]);
+
+ const openWithQuery = useCallback((query: string) => {
+ if (window.Kapa) {
+ window.Kapa.open({
+ mode: 'ai',
+ query: `Suggest a solution or troubleshooting steps for the following error: ${query}`,
+ submit: true,
+ });
+
+ // Move widget container inside screen overlay so it appears on top
+ const moveContainer = () => {
+ const container = document.getElementById(
+ 'kapa-widget-container'
+ );
+ const overlay = document.querySelector(
+ '.components-modal__screen-overlay'
+ );
+ if (container && overlay) {
+ overlay.insertBefore(container, overlay.firstChild);
+ } else {
+ setTimeout(moveContainer, 50);
+ }
+ };
+ setTimeout(moveContainer, 50);
+ }
+ }, []);
+
+ return {
+ isConfigured,
+ isLoaded,
+ openWithQuery,
+ };
+}
diff --git a/packages/playground/website/vite.config.ts b/packages/playground/website/vite.config.ts
index 141daa83c8..3594143c60 100644
--- a/packages/playground/website/vite.config.ts
+++ b/packages/playground/website/vite.config.ts
@@ -105,6 +105,13 @@ export default defineConfig(({ command, mode }) => {
content: `
export const corsProxyUrl = ${JSON.stringify(corsProxyUrl || undefined)};`,
}),
+ virtualModule({
+ name: 'kapa-ai-config',
+ content: `
+ export const kapaWebsiteId = ${JSON.stringify(
+ process.env.KAPA_WEBSITE_ID || ''
+ )};`,
+ }),
// GitHub OAuth flow
{
name: 'configure-server',