How to integrate Glow into a consuming app
The Glow packages (@zooly/glow-client and @zooly/glow-server) are consumed by apps (e.g., zooly-app) through API routes and the GlowChatClient component. The client expects a base URL for API calls; the app implements the corresponding routes and delegates to glow-server.
To integrate Glow into an app:
@zooly/glow-client and @zooly/glow-server to package.jsontranspilePackages in next.config.tsGlowChat (e.g., for a given chatId and glowSlug)GlowChatClient with the glowChat and optional chatBrandingSettings// Add to transpilePackages
transpilePackages: [
"@zooly/glow-client",
"@zooly/glow-server",
// ... other packages
],
The client uses a configurable base URL (default: /api/glow-chat-client). All routes are relative to this base.
Main streaming endpoint. The client sends messages, id (glowChatId), mockStateId, and location.
import { NextRequest } from "next/server";
import { handleGlowChatStream } from "@zooly/glow-server";
import { getServerSession } from "next-auth";
export async function POST(request: NextRequest) {
const session = await getServerSession(authOptions);
return handleGlowChatStream(request, session ?? undefined);
}
Resets the chat to a specific message. Used when the user clicks "Edit" on a message.
Resets a tool call (e.g., when user cancels or retries).
Saves clientMsgState (form data, tool outputs) for the chat.
Returns public message data for display.
The exact implementation of these routes depends on the app. The glow-client's useGlowChat hook accepts a url prop to override the base path (e.g., url: "/api/glow-chat-client").
Before rendering GlowChatClient, the app must obtain a GlowChat. Use getOrCreateGlowChat for flows that support both new and existing chats:
import { getOrCreateGlowChat } from "@zooly/glow-server";
const { glowChat, glowSettings } = await getOrCreateGlowChat({
chatId: "unique-chat-id", // Optional; if omitted or restart, creates new
glowSlug: "backstage-mini-app", // Required for new chats
restart: false, // If true, creates new chat even with chatId
phoneNumber: null,
email: null,
userName: user?.name ?? null,
mockStateId: null, // For testing with @zooly/llm-mock
});
For generate/embed flows (e.g., server-side generation), use handleGlowChatGenerate:
import { handleGlowChatGenerate } from "@zooly/glow-server";
const result = await handleGlowChatGenerate({
options: {
chatId,
glowSlug: "my-flow",
mockStateId,
// ...
},
messageStr: "User's initial message",
});
import { GlowChatClient } from "@zooly/glow-client";
import type { GlowChat } from "@zooly/types";
interface ChatPageProps {
glowChat: GlowChat;
chatBrandingSettings?: ChatBrandingSettings; // Optional
}
export function ChatPage({ glowChat, chatBrandingSettings }: ChatPageProps) {
return (
<GlowChatClient
glowChat={glowChat}
chatBrandingSettings={chatBrandingSettings}
/>
);
}
GlowChatClient uses useGlowChat with url: "/api/glow-chat-client" by default. To use a different base path, you would need to extend or wrap the component to pass a custom url.
GlowChat (e.g., via getOrCreateGlowChat in an API route or server component)glowChat to GlowChatClient/api/glow-chat-client with messages and glowChatIdGlowChatMessageQueueTOOL_REGISTRY); user interacts; client sends tool output back via addToolOutputhandleGlowChatStream accepts an optional session. If the chat has a userId and it doesn't match the session user, the request returns 401. For guest/unauthenticated chats, userId can be null initially and is updated when the user logs in.
NEXT_PUBLIC_URL - Used by executeApiTool when tool urlApi is relative (e.g., /api/my-tool)On This Page
OverviewSetup ChecklistPackage Configurationnext.config.tsAPI RoutesPOST (base URL) — Stream Chat CompletionPOST (base URL)/reset-to-messagePOST (base URL)/reset-tool-callPOST (base URL)/client-msg-state/savePOST (base URL)/message-data/get-public-dataCreating a Glow ChatComponent UsageTypical FlowAuthenticationEnvironment VariablesRelated Documentation