ADK Frontend Integration
Use this skill when users ask questions about building frontend applications that connect to Botpress ADK bots. This covers authentication patterns, type-safe API calls, client configuration, and integrating generated types.
What is ADK Frontend Integration?
When you build a bot with the Botpress ADK, you often need a frontend application that interacts with it. This skill provides production-tested patterns for:
- •Authentication - Cookie-based PAT storage with OAuth flow
- •Client Management - Zustand store pattern for client caching and reuse
- •Type Generation - Using ADK-generated types for full type safety
- •Action Calls - Calling bot actions with proper error handling and optimistic updates
Key Technologies
- •@botpress/client - Official TypeScript client for Botpress API
- •Triple-slash references - TypeScript pattern for importing generated types
- •React Query - For mutations and cache management (optional but recommended)
- •Zustand - For client state management
When to Use This Skill
Activate this skill when users ask frontend-related questions like:
Authentication Questions
- •"How do I authenticate with Botpress from my frontend?"
- •"What are Personal Access Tokens (PATs)?"
- •"Should I use cookies or localStorage for tokens?"
- •"How do I implement OAuth login flow?"
- •"How do I protect routes based on authentication?"
- •"How do I handle token expiration?"
Client Setup Questions
- •"How do I initialize the Botpress client?"
- •"What's the best way to manage multiple client instances?"
- •"Why use a client store?"
- •"How do I create workspace-scoped vs bot-scoped clients?"
- •"What's the difference between regular client and Zai client?"
Type Generation Questions
- •"How do I get types for my bot's actions?"
- •"What are triple-slash references?"
- •"How do I import generated types?"
- •"Where are the .adk type files?"
- •"How do I keep types in sync between bot and frontend?"
- •"Why can't TypeScript find my action types?"
Calling Actions Questions
- •"How do I call a bot action from my frontend?"
- •"What's the syntax for client.callAction()?"
- •"How do I handle errors when calling actions?"
- •"How do I implement optimistic updates?"
- •"How do I chain multiple action calls?"
- •"How do I use React Query with bot actions?"
Available Documentation
Documentation files in ./references/:
Core Integration Patterns
- •authentication.md - Complete authentication system with PATs, cookies, OAuth, route protection
- •botpress-client.md - Client initialization, Zustand store pattern, Zai client setup
- •calling-actions.md - Type-safe action calls, mutations, error handling, optimistic updates
- •type-generation.md - Triple-slash references, generated types, maintaining type safety
How to Answer Frontend Questions
Frontend questions typically fall into these categories:
1. Authentication Implementation
When users ask about authentication, reference the complete pattern from authentication.md:
Key Concepts:
- •PAT generation in Botpress Cloud
- •Cookie-based storage (not localStorage)
- •AuthContext with React Context API
- •OAuth callback flow via cli-login
- •Route protection with TanStack Router
- •Profile fetching from both Botpress API and bot tables
Response Pattern:
- •Explain the authentication strategy (cookies vs localStorage)
- •Show the AuthProvider implementation
- •Demonstrate the OAuth flow
- •Provide route protection examples
- •Highlight security best practices
2. Client Setup and Management
When users ask about client configuration, reference botpress-client.md:
Key Concepts:
- •Client initialization with apiUrl, workspaceId, token, botId
- •Zustand store for client caching
- •Dynamic client keys for reuse
- •Workspace-scoped vs bot-scoped clients
- •Extended timeouts for Zai operations
Response Pattern:
- •Show the clientsStore.ts pattern
- •Explain how client caching works
- •Demonstrate getApiClient() usage
- •Show when to use workspace vs bot-scoped clients
- •Explain getZaiClient() for AI operations
3. Type Generation and Import
When users ask about types, reference type-generation.md:
Key Concepts:
- •ADK generates types in
.adk/directory during dev/build - •Triple-slash directives for referencing external types
- •Generated files: action-types.d.ts, table-types.d.ts, workflow-types.d.ts
- •Creating type aliases for cleaner code
- •Keeping types in sync with adk dev
Response Pattern:
- •Explain how ADK generates types
- •Show triple-slash reference syntax
- •Demonstrate importing generated types
- •Provide examples of creating type aliases
- •Show how types stay in sync automatically
4. Calling Bot Actions
When users ask about calling actions, reference calling-actions.md:
Key Concepts:
- •client.callAction() signature
- •Type-safe input/output with BotActionDefinitions
- •Service layer pattern for reusable action calls
- •Using useMutation for loading states and error handling
- •Optimistic updates for instant UI feedback
- •Chaining actions (sequential vs parallel)
Response Pattern:
- •Show the basic callAction() syntax
- •Demonstrate type-safe service functions
- •Provide useMutation examples
- •Show error handling patterns
- •Explain optimistic updates when relevant
Common Patterns Reference
Authentication Flow
// 1. Cookie helpers
function setCookie(name: string, value: string, days = 365);
function getCookie(name: string): string | null;
function deleteCookie(name: string);
// 2. AuthContext
interface AuthContextType {
token: string | null;
isAuthenticated: boolean;
userProfile: UserProfile | null;
isLoadingProfile: boolean;
login: (token: string) => void;
logout: () => void;
}
// 3. OAuth Flow
// Redirect: https://app.botpress.cloud/cli-login?redirect=...
// Callback: /auth/callback?pat=bp_pat_...
// Store PAT in cookie and navigate to app
Client Store Pattern
// stores/clientsStore.ts
const useClientsStore = create<ClientsState>()((set, get) => ({
APIClients: {},
getAPIClient: (props) => {
const key = props?.botId
? `${props.workspaceId}-${props.botId}`
: (props?.workspaceId ?? DEFAULT_API_CLIENT_KEY);
const cached = get().APIClients[key];
if (cached) return cached;
const newClient = new APIClient({
apiUrl: API_BASE_URL,
workspaceId: props?.workspaceId,
token: getPat() ?? "",
botId: props?.botId,
});
set((state) => ({
APIClients: { ...state.APIClients, [key]: newClient },
}));
return newClient;
},
}));
export const getApiClient = (props?) =>
useClientsStore.getState().getAPIClient(props);
Type Import Pattern
// types/index.ts
/// <reference path="../../../bot/.adk/action-types.d.ts" />
/// <reference path="../../../bot/.adk/table-types.d.ts" />
import type { BotActionDefinitions } from "@botpress/runtime/_types/actions";
import type { TableDefinitions } from "@botpress/runtime/_types/tables";
// Create type aliases
export type SendMessageAction = BotActionDefinitions["sendMessage"];
export type TicketTableRow = TableDefinitions["TicketsTable"]["Output"];
Action Call Pattern
// services/bot-service.ts
export async function sendMessage(input: SendMessageAction["input"]) {
const client = getApiClient({ botId, workspaceId });
const result = await client.callAction({
type: "sendMessage",
input,
});
return result.output as SendMessageAction["output"];
}
// Component usage with useMutation
const { mutate: send, isPending } = useMutation({
mutationFn: sendMessage,
onSuccess: () => {
toast.success("Message sent");
queryClient.invalidateQueries({ queryKey: ["messages"] });
},
onError: (error) => {
toast.error("Failed to send message");
},
});
Examples of Questions This Skill Answers
Beginner Questions
- •"How do I connect my React app to a Botpress bot?"
- •"What is a Personal Access Token?"
- •"Where do I find my workspace ID and bot ID?"
- •"How do I install @botpress/client?"
Authentication Questions
- •"How should I store authentication tokens?"
- •"How do I implement login/logout?"
- •"How do I protect authenticated routes?"
- •"Should I use cookies or localStorage?"
- •"How do I handle the OAuth callback?"
Type Safety Questions
- •"How do I get TypeScript types for my bot?"
- •"What are triple-slash references?"
- •"Why can't TypeScript find my action types?"
- •"How do I keep types in sync?"
- •"Where are the generated type files?"
Implementation Questions
- •"How do I call a bot action?"
- •"How do I query bot tables from my frontend?"
- •"How do I handle loading states?"
- •"How do I implement optimistic updates?"
- •"How do I chain multiple action calls?"
Advanced Questions
- •"How do I use Zai from my frontend?"
- •"What's the difference between workspace and bot-scoped clients?"
- •"How do I implement client caching?"
- •"How do I handle token expiration?"
- •"How do I implement retry logic?"
Response Format
When answering:
- •Start with a concise explanation (1-2 paragraphs)
- •Provide working code examples from the references
- •Include file references (e.g., "From authentication.md:60-85")
- •Highlight security considerations when relevant
- •Show common pitfalls and how to avoid them
- •Link to related topics for deeper exploration
Example Response Structure
Question: "How do I authenticate users in my frontend?" Answer: The recommended pattern uses cookie-based PAT storage with OAuth flow. Here's the complete implementation: 1. Cookie Helpers (authentication.md:89-111) [code example] 2. AuthContext Setup (authentication.md:64-76) [code example] 3. OAuth Flow (authentication.md:473-533) [code example] Key Security Considerations: - Use SameSite=Lax for CSRF protection - Always use HTTPS in production - Never log PATs to console - Implement token expiration handling Related Topics: - Route protection: authentication.md:369-467 - Profile fetching: authentication.md:304-347 - Client initialization: botpress-client.md:29-51
Critical Patterns to Always Reference
When answering questions, always verify these patterns against the documentation:
1. Client Management
// ✅ CORRECT - Use client store
const client = getApiClient({ workspaceId, botId });
// ❌ WRONG - Create new client every time
const client = new Client({ apiUrl, workspaceId, token, botId });
2. Type Imports
// ✅ CORRECT - Triple-slash at top of file
/// <reference path="../../../bot/.adk/action-types.d.ts" />
import type { BotActionDefinitions } from "@botpress/runtime/_types/actions";
// ❌ WRONG - No triple-slash reference
import type { BotActionDefinitions } from "@botpress/runtime/_types/actions";
3. Action Calls
// ✅ CORRECT - Service layer with types
export async function sendMessage(input: SendMessageAction["input"]) {
const client = getApiClient({ botId, workspaceId });
const result = await client.callAction({ type: "sendMessage", input });
return result.output as SendMessageAction["output"];
}
// ❌ WRONG - Direct call in component
const result = await client.callAction({ type: "sendMessage", input: data });
4. Authentication Storage
// ✅ CORRECT - Cookie with SameSite
document.cookie = `token=${value};expires=${expires};path=/;SameSite=Lax`;
// ❌ WRONG - localStorage without security
localStorage.setItem("token", value);
Best Practices to Emphasize
When answering, always mention relevant best practices:
Security
- •Always use HTTPS in production
- •Use cookies with SameSite protection
- •Never log PATs or tokens
- •Implement token expiration handling
- •Use HttpOnly cookies when possible (SSR)
Type Safety
- •Always use generated types from ADK
- •Create type aliases for cleaner code
- •Use triple-slash references correctly
- •Keep types in sync with adk dev
- •Type all action inputs and outputs
Performance
- •Cache clients with Zustand store
- •Use workspace-scoped clients when no bot operations needed
- •Implement optimistic updates for better UX
- •Use React Query for cache management
- •Run independent actions in parallel
Error Handling
- •Always handle 401 (expired token) errors
- •Provide user feedback on errors
- •Implement retry logic for transient failures
- •Log errors appropriately (never log tokens)
- •Show loading states during async operations
Code Organization
- •Use service layer for action calls
- •Centralize types in single file
- •Keep authentication logic in context
- •Separate client configuration from usage
- •Reuse service functions across components
Troubleshooting Common Issues
Be prepared to help with these common problems:
"Cannot find module '@botpress/runtime/_types/actions'"
- •Check triple-slash reference path
- •Verify .adk/ directory exists
- •Restart TypeScript server
- •Ensure adk dev/build has run
"Types not updating after bot changes"
- •Restart adk dev
- •Delete .adk/ and rebuild
- •Restart TypeScript server
- •Check for bot compilation errors
"Authentication fails after reload"
- •Implement reload retry logic (authentication.md:191-220)
- •Check cookie expiration
- •Verify token is being retrieved correctly
- •Check for CORS issues
"Client timeout on long operations"
- •Use getZaiClient() with extended timeout for AI operations
- •Don't use regular client for Zai operations
- •Consider breaking into smaller operations
Summary
This skill covers the complete frontend integration story for Botpress ADK:
Core Topics:
- •Authentication with PATs and cookies
- •Client management with Zustand
- •Type generation and import with triple-slash references
- •Calling bot actions with full type safety
When to Use:
- •Any frontend integration question
- •Authentication and security patterns
- •Type safety and generated types
- •Client setup and configuration
- •Action calls and error handling
Key Principle: Always provide production-ready patterns that emphasize type safety, security, and maintainability.