Getting Started
Installation
npm install @guidekit/core @guidekit/react @guidekit/serverFor voice support, also install the VAD package:
npm install @guidekit/vadSetup with CLI (recommended)
The fastest way to get started with proxy mode (API keys stay on the server):
npx @guidekit/cli initFor Next.js App Router, init scaffolds:
lib/guidekit-routes.ts— shared proxy route handlersapp/api/guidekit/{token,llm,health}/route.ts— server routesapp/providers.tsx—GuideKitProviderwithtokenEndpoint,proxy, andllmmodel config.env.localtemplate with required keys
Use npx @guidekit/cli init --platform to also scaffold STT/TTS routes and Platform Mode provider props.
Then generate a signing secret:
npx @guidekit/cli generate-secretAdd the secret and your API keys to .env.local:
GUIDEKIT_SECRET=your-generated-secret
LLM_API_KEY=your-llm-api-key
STT_API_KEY=your-stt-api-key # Optional, for voice
TTS_API_KEY=your-tts-api-key # Optional, for voiceWrap your root layout with the generated Providers component (or let init patch layout.tsx for you):
// app/layout.tsx
import { Providers } from './providers';
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}Verify setup
npx @guidekit/cli doctorDoctor checks environment variables, installed packages, proxy route files, provider wiring, and (when your dev server is running) local /api/guidekit/token and /api/guidekit/health endpoints.
Manual Setup (Next.js App Router)
If you prefer to wire routes yourself, mirror the example app pattern.
1. Shared proxy routes
// lib/guidekit-routes.ts
import { createNextAppRouterRoutes, getSharedSessionStore } from '@guidekit/server/next';
export const guidekitRoutes = createNextAppRouterRoutes({
signingSecret: process.env.GUIDEKIT_SECRET!,
sessionStore: getSharedSessionStore(),
createTokenOptions: () => ({
llmApiKey: process.env.LLM_API_KEY!,
sttApiKey: process.env.STT_API_KEY,
ttsApiKey: process.env.TTS_API_KEY,
expiresIn: '15m',
}),
});2. API routes
// app/api/guidekit/token/route.ts
import { guidekitRoutes } from '../../../../lib/guidekit-routes';
export const POST = guidekitRoutes.POST_token;// app/api/guidekit/llm/route.ts
import { guidekitRoutes } from '../../../../lib/guidekit-routes';
export const POST = guidekitRoutes.POST_llm;// app/api/guidekit/health/route.ts
import { guidekitRoutes } from '../../../../lib/guidekit-routes';
export const GET = guidekitRoutes.GET_health;3. Provider
'use client';
// app/providers.tsx
import { GuideKitProvider } from '@guidekit/react';
export function Providers({ children }: { children: React.ReactNode }) {
return (
<GuideKitProvider
tokenEndpoint="/api/guidekit/token"
proxy={{ llm: '/api/guidekit/llm', health: '/api/guidekit/health' }}
llm={{ provider: 'gemini', model: 'gemini-2.5-flash' }}
agent={{
name: 'Guide',
greeting: 'Hi! How can I help you today?',
}}
options={{
mode: 'text',
debug: process.env.NODE_ENV === 'development',
}}
>
{children}
</GuideKitProvider>
);
}Quick Prototyping (Dev Only)
For quick prototyping without server routes, pass API keys directly:
<GuideKitProvider
llm={{ provider: 'gemini', apiKey: 'your-key' }}
agent={{ name: 'Guide' }}
>
{children}
</GuideKitProvider>Warning: This exposes keys in the browser. Only use for local development. Production apps should use proxy mode and a token endpoint — see Server SDK.
Framework Support
| Framework | Support |
|---|---|
| Next.js App Router | Full (recommended) |
| Next.js Pages Router | Full |
| Vite + React | Full |
| Create React App | Full |
| Non-React (vanilla JS) | Via @guidekit/vanilla |
SPA navigation (Next.js App Router)
GuideKit detects URL changes via the Navigation API, popstate, and polling. For client-side route changes that bypass full page loads, pass your App Router instance so navigate() and post-nav rescans stay reliable:
'use client';
import { useRouter } from 'next/navigation';
import { GuideKitProvider } from '@guidekit/react';
export function Providers({ children }: { children: React.ReactNode }) {
const router = useRouter();
return (
<GuideKitProvider
tokenEndpoint="/api/guidekit/token"
proxy={{ llm: '/api/guidekit/llm', health: '/api/guidekit/health' }}
llm={{ provider: 'gemini', model: 'gemini-2.5-flash-lite' }}
siteKnowledge={{ endpoint: '/api/guidekit/site-search', topK: 5 }}
navigation={{ router: { push: (href) => router.push(href) } }}
options={{
autonomy: {
level: 'guided',
allowNavigation: true,
allowSafeClicks: true,
requireConfirmationFor: ['submit', 'purchase', 'destructive', 'auth'],
},
}}
>
{children}
</GuideKitProvider>
);
}On each route change, GuideKit clears PageMemory, rescans the DOM, and emits dom:route-change plus context:memory-cleared.
For in-page DOM swaps (tabs, modals, virtual lists) without a URL change, call core.rescanPage() after updating the UI so the assistant sees fresh sections:
'use client';
import { useEffect, useState } from 'react';
import { useGuideKitCore } from '@guidekit/react';
export function TabPanel({ activeTab }: { activeTab: string }) {
const core = useGuideKitCore();
useEffect(() => {
if (core?.isReady) core.rescanPage();
}, [activeTab, core]);
return <div>{/* tab content */}</div>;
}Universal site checklist
- Proxy mode:
tokenEndpoint+/api/guidekit/llm(never ship LLM keys to the browser) - Optional
contentMapfor product facts the DOM cannot infer - Optional
data-guidekit-targeton critical CTAs (improves accuracy, not required) clickableSelectors.allow/denyfor production click boundariessiteKnowledge={{ endpoint: '/api/guidekit/site-search' }}for full-site contextoptions.autonomyfor guided navigation/click policy- Redis session store for multi-instance deployments
hallucinationGuard={true}+intelligence={true}for Platform Mode on public sites
See the example app routes /plain, /spa-rescan, and /iframe-test for unannotated page demos used in contract E2E.
Next Steps
- Provider Setup — Configuration options in depth
- Custom UI (Headless) — Build your own assistant UI with hooks
- Platform Mode — Intelligence, knowledge RAG, and plugins (see the full example app)
- Hooks API — Using hooks in your components
- Architecture — How GuideKit works under the hood