Skip to main content
Build simple React pages you can use as dashboards or embed in the inbox sidebar.
Experimental feature. API may change.

Basics

Project pages let you create custom React interfaces that run inside Kapso. Each page is written in TSX and compiled on save into a single HTML artifact, rendered in a sandboxed iframe. Create pages at Project → Pages. Pages can be draft or published. Project owners and admins can create and edit pages; members can view them.

Build a page

The easiest way to build a page is with the Kapso Agent — just ask it to create a page and describe what you want. The agent will generate the TSX for you. To build manually:
  1. Go to Project → PagesNew page
  2. Set name, slug, description
  3. Write TSX, use the preview
  4. Save to compile
"use client";
import React, { useState } from "react";
import { createRoot } from "react-dom/client";

function App() {
  const [result, setResult] = useState(null);

  async function load() {
    await kapso.ready();
    const data = await kapso.invokeFunction({
      slug: "your-function-slug",
      payload: { id: "123" },
    });
    setResult(data);
  }

  return (
    <div style={{ fontFamily: "system-ui", padding: 24 }}>
      <button onClick={load}>Load</button>
      <pre>{result ? JSON.stringify(result, null, 2) : "No data"}</pre>
    </div>
  );
}

const root = document.getElementById("root");
if (root) createRoot(root).render(<App />);

Call functions

Pages can call your deployed Kapso functions using the built-in kapso bridge. First, wait for the bridge to initialize with kapso.ready(). Then call kapso.invokeFunction() with either the function’s id or slug, plus an optional payload. The function returns JSON (or text) from your function’s response, and throws on errors.
await kapso.ready();
const data = await kapso.invokeFunction({ slug: "get-orders", payload: { limit: 10 } });

Context

When a page is mounted in the inbox, you can access conversation data through kapso.getContext(). This gives you the current conversation’s phone number, contact info, and any metadata.
const ctx = kapso.getContext();
{
  "system": {
    "projectId": "...",
    "pageId": "...",
    "viewerUserId": "...",
    "mountPoint": "inbox_conversation_sidebar",
    "mode": "regular"
  },
  "context": {
    "conversation": {
      "id": "...",
      "phoneNumber": "+1415...",
      "whatsappContactId": "...",
      "whatsappConfigId": "...",
      "whatsappPhoneNumberId": "...",
      "contactName": "..."
    }
  },
  "vars": {},
  "metadata": {}
}

Inbox mount

Pages can be mounted directly in the inbox sidebar, appearing as a Page tab in the conversation detail panel. Toggle Inbox mount in page settings to enable this. The mount point key is inbox_conversation_sidebar. Only one page per mount point per project. The embedded inbox only serves published pages.

Limits

Pages run in a sandboxed iframe with no access to cookies, localStorage, or the parent DOM. You can load external libraries and call external URLs, but CORS restrictions apply. Source size is limited to 1 MB. TSX only — no asset uploads or public URLs yet.