Skip to Content
AgentPress is finally here! 🎉
Configuring Portal Apps

Configuring a Portal App

Learn how to set up a standalone chat portal that can be embedded in websites or used as a standalone application.

Overview

A portal app is a lightweight chat interface that connects to your AgentPress API. The portal app serves as the recommended template for creating embedded chat widgets or standalone chat applications.

Basic Setup

1. Routes Configuration

Configure your app in src/routes.tsx with the AgentPressProvider:

import { EAppType } from "@agentpress/lib/types"; import { AgentPressProvider, Chat } from "@agentpress/ui/core"; import { toolsUI } from "@repo/custom/ui"; import { Toaster } from "@agentpress/ui/ui"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import { createRootRoute, createRoute, Outlet } from "@tanstack/react-router"; const config = { apiHost: import.meta.env.VITE_API_HOST || "http://localhost:3001", toolsUI, isGuest: true, voiceTranscription: true, appType: EAppType.PORTAL, }; const rootRoute = createRootRoute({ component: () => ( <AgentPressProvider config={config}> <Outlet /> <ReactQueryDevtools /> <Toaster /> </AgentPressProvider> ), }); // Add your chat and login routes const indexRoute = createRoute({ getParentRoute: () => rootRoute, path: "/", component: ChatPage, }); const loginRoute = createRoute({ getParentRoute: () => rootRoute, path: "/login", component: LoginPage, }); export const routeTree = rootRoute.addChildren([indexRoute, loginRoute]);

Note: Unlike console apps, portal apps typically don’t use beforeLoad auth guards, so you don’t need to call setAgentPressConfig() separately. The AgentPressProvider handles the configuration internally.

The AgentPressProvider handles all necessary setup including:

  • React Query client for data fetching
  • Theme provider for light/dark mode
  • Task WebSocket management via Zustand
  • Tooltip provider
  • Error boundary for graceful error handling

2. Main Application

In your main.tsx, set up routing:

import { StrictMode } from "react"; import ReactDOM from "react-dom/client"; import { RouterProvider, createRouter } from "@tanstack/react-router"; import { routeTree } from "./routes"; const router = createRouter({ routeTree }); const rootElement = document.getElementById("root")!; const root = ReactDOM.createRoot(rootElement); root.render( <StrictMode> <RouterProvider router={router} /> </StrictMode> );

Configuration Options

Core Configuration

The config prop passed to AgentPressProvider accepts these options:

  • apiHost (required) - URL of your AgentPress API server
  • toolsUI (required) - Custom tool UI components from your custom package
  • appType (required) - EAppType.PORTAL or EAppType.CONSOLE
  • isGuest (optional) - Allow guest access without authentication
  • voiceTranscription (optional) - Enable voice-to-text functionality (default: true)

Environment Variables

Set up your environment variables:

# .env VITE_API_HOST=https://your-api-domain.com

Chat Component Configuration

URL Parameters

The chat component supports various URL parameters for customization:

const chatSearchSchema = z.object({ agentId: z.string().optional().default(""), disableThreadList: z.boolean().optional().default(false), hideUsername: z.boolean().optional().default(false), hideAgents: z.boolean().optional().default(false), disableUpload: z.boolean().optional().default(false), sidebarOpen: z.boolean().optional().default(true), hideNewThread: z.boolean().optional().default(false), disableFeedback: z.boolean().optional().default(false), initialUserMessage: z.string().optional().default(""), authToken: z.string().optional().default(""), threadId: z.string().optional().default(""), });

Chat Component Usage

<Chat defaultAgentId={agentId} disableThreadList={disableThreadList} hideUsername={hideUsername} hideAgents={hideAgents} disableUpload={disableUpload} hideNewThread={hideNewThread} sidebarOpen={sidebarOpen} disableFeedback={disableFeedback} initialUserMessage={initialUserMessage} initialThreadId={threadId} />

Embedding Options

URL Parameters for Embedding

Customize the chat interface using URL parameters:

https://your-portal.com/?agentId=agent-123&disableThreadList=true&hideUsername=true

Common parameters:

  • agentId - Specific agent to use
  • disableThreadList - Hide the conversation history sidebar
  • hideUsername - Don’t display usernames
  • hideAgents - Hide agent selection dropdown
  • disableUpload - Disable file upload functionality
  • hideNewThread - Hide new conversation button
  • initialUserMessage - Pre-populate the input field
  • authToken - Authenticate with a specific token

iFrame Embedding

Embed the portal in any website:

<iframe src="https://your-portal.com/?disableThreadList=true&hideUsername=true&hideSettings=true" className="w-[700px] max-w-full max-h-[900px] h-full overflow-hidden m-4 border-2 border-secondary rounded-2xl" allow="microphone; clipboard-read; clipboard-write; camera; geolocation; fullscreen;" sandbox="allow-same-origin allow-scripts allow-popups allow-forms allow-downloads allow-modals allow-presentation allow-storage-access-by-user-activation" frameborder="0"> </iframe>

iFrame Security and Permissions

Allow Attributes:

  • microphone - Enable voice input functionality
  • clipboard-read; clipboard-write - Allow copy/paste operations
  • camera - Enable camera access for file uploads
  • geolocation - Allow location-based features
  • fullscreen - Enable fullscreen mode

Sandbox Attributes:

  • allow-same-origin - Allow access to same-origin resources
  • allow-scripts - Enable JavaScript execution
  • allow-popups - Allow popup windows (for file downloads)
  • allow-forms - Enable form submissions
  • allow-downloads - Allow file downloads
  • allow-modals - Enable modal dialogs
  • allow-presentation - Allow presentation API
  • allow-storage-access-by-user-activation - Enable storage access

Authentication

Guest Mode

Enable guest access without login in your config:

<AgentPressProvider config={{ isGuest: true, // ... other options }} > {/* ... */} </AgentPressProvider>

Token-Based Authentication

Pass authentication tokens via URL:

https://your-portal.com/?authToken=your-jwt-token

The portal will automatically attempt login with the provided token.

Deployment

Build for Production

# From portal app directory bun run build

Environment Configuration

Set production environment variables:

# Production .env VITE_API_HOST=https://api.yourcompany.com

Static Hosting

The built portal is officially supported on AWS:

  • AWS S3 + CloudFront (officially supported via Terraform)

Customization

Custom Tool UIs

Import and configure your custom tool UIs in the provider config:

import { toolsUI } from "@repo/custom/ui"; <AgentPressProvider config={{ toolsUI, // ... other options }} > {/* ... */} </AgentPressProvider>

Header Customization

Customize or hide the header:

{!disableThreadList && ( <header className="h-16 w-full flex items-center justify-center border-b"> <AgentPressLogo /> <AgentPressLogoLabel /> </header> )}

Best Practices

Security

  • Validate auth tokens on the server side
  • Set CORS policies appropriately on your API
  • Limit guest access if handling sensitive data

Performance

  • Enable compression for static assets
  • Use CDN for global distribution
  • Optimize images and assets
  • Monitor bundle size with build tools

User Experience

  • Set appropriate defaults for your use case
  • Test on mobile devices for responsive design
  • Provide loading states for better UX
  • Handle network errors gracefully

Troubleshooting

Connection Issues

Portal can’t connect to API:

  • Check VITE_API_HOST environment variable
  • Verify API server is running and accessible
  • Check CORS configuration on API server

Authentication failures:

  • Verify auth tokens are valid
  • Check token expiration
  • Ensure API authentication endpoints are working

Your portal app is now ready to provide a seamless chat experience for your users!

Last updated on