npx skills add ...
npx skills add botpress/skills --skill adk-frontend
Guidelines for building frontend applications that integrate with Botpress ADK bots - covering authentication, type generation, client setup, and calling bot actions
npx skills add botpress/skills --skill adk-frontend
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.
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:
Activate this skill when users ask frontend-related questions like:
Documentation files in ./references/:
Frontend questions typically fall into these categories:
When users ask about authentication, reference the complete pattern from authentication.md:
Key Concepts:
Response Pattern:
When users ask about client configuration, reference botpress-client.md:
Key Concepts:
Response Pattern:
When users ask about types, reference type-generation.md:
Key Concepts:
.adk/ directory during dev/buildResponse Pattern:
When users ask about calling actions, reference calling-actions.md:
Key Concepts:
Response Pattern:
When answering:
When answering questions, always verify these patterns against the documentation:
When answering, always mention relevant best practices:
Be prepared to help with these common problems:
This skill covers the complete frontend integration story for Botpress ADK:
Core Topics:
When to Use:
Key Principle: Always provide production-ready patterns that emphasize type safety, security, and maintainability.
// 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)// 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']// 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')
},
})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// ✅ CORRECT - Use client store
const client = getApiClient({ workspaceId, botId })
// ❌ WRONG - Create new client every time
const client = new Client({ apiUrl, workspaceId, token, botId })// ✅ 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'// ✅ 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 })// ✅ CORRECT - Cookie with SameSite
document.cookie = `token=${value};expires=${expires};path=/;SameSite=Lax`
// ❌ WRONG - localStorage without security
localStorage.setItem('token', value)