Skip to main content

Availability

Portal UI plugins extend the AI Portal (end-user facing) with custom pages, forms, and interactive features. Unlike Admin UI plugins which are only visible to administrators, Portal UI plugins are accessible to all authenticated portal users and support group-based visibility filtering.

Overview

Portal UI plugins enable you to:
  • Add Portal Pages: Register new routes in the portal navigation
  • Extend Portal Sidebar: Add sections and links to the portal drawer
  • Serve WebComponents: Use any frontend framework (same asset serving as admin UI)
  • Handle Portal RPC: Define backend endpoints that receive authenticated user context
  • Control Visibility: Restrict portal pages to specific user groups
  • Combine with Admin UI: A single plugin can have both admin and portal interfaces

Use Cases

  • Support ticket systems for end users
  • Custom resource browsers or dashboards
  • User feedback and survey forms
  • Forum or community features
  • Self-service configuration pages
  • Data submission and approval workflows

Architecture

Portal UI plugins use a separate security scope from admin UI plugins. This is enforced at every level:
Key security boundaries:

Quick Start

1. Project Structure

2. Create Manifest

The manifest declares both admin (ui) and portal (portal) UI sections. The portal section uses PortalUISlot which includes a groups field for visibility filtering.
Expandable

Group-Based Visibility

The groups field on portal slots controls which users can see the page: The filtering happens server-side — the portal UI registry and sidebar menu endpoints only return entries the authenticated user is allowed to see.

3. Implement the Plugin

A portal UI plugin must implement both UIProvider (for assets and manifest) and PortalUIProvider (for portal RPC):
Expandable

4. Create Portal WebComponent

Portal WebComponents receive a portalPluginAPI object (injected by the portal plugin loader) for making RPC calls:
Expandable
Key difference from admin WebComponents:
  • Admin components receive this.pluginAPI (routes to HandleRPC)
  • Portal components receive this.portalPluginAPI (routes to HandlePortalRPC)

5. Create Admin WebComponent (Optional)

If your plugin also has an admin interface, create a separate WebComponent that uses this.pluginAPI:
Expandable

PortalUserContext

Every portal RPC call includes a PortalUserContext with the authenticated user’s information:
Use this context for:
  • Authorization: Check if the user has permission for the requested operation
  • Data scoping: Return only data belonging to the calling user
  • Audit logging: Record who performed each action
  • Group-based features: Enable features based on group membership
Expandable

Manifest Reference

Portal Slots

The portal section in the manifest is parallel to the ui section:
Expandable

Capabilities and Permissions

Portal UI plugins must declare both hook types and permissions:
  • studio_ui in hooks enables admin UI + asset serving
  • portal_ui in hooks enables portal RPC handling
  • Both are required for a plugin with portal UI (assets are served via UIProvider)

Route Path Convention

Portal plugin routes should follow the pattern /portal/plugins/{plugin-name}/{page} to avoid conflicts with built-in portal routes:

API Endpoints

Portal plugin API endpoints are under /common/ (authenticated, no admin required):

Portal RPC Call Flow

Example: Portal Feedback Plugin

A complete working example is available at examples/plugins/studio/portal-feedback/. This plugin demonstrates:
  • Portal form for users to submit feedback (HandlePortalRPC)
  • Admin dashboard to view all submissions (HandleRPC)
  • Shared asset serving between admin and portal UIs
  • Group-based visibility (set to [] for all users)
  • waitForAPIAndLoad() pattern for WebComponent API injection timing

Best Practices

Security

  1. Never trust portal input - Always validate and sanitize data in HandlePortalRPC
  2. Scope data to users - Use userCtx.UserID to ensure users only see their own data
  3. Keep admin operations in HandleRPC - Destructive operations (delete, admin overrides) should stay in the admin-only HandleRPC method
  4. Check groups in RPC handlers - Even though sidebar visibility is filtered, users could call the RPC endpoint directly. Validate group membership in HandlePortalRPC for sensitive operations

Performance

  1. Use KV storage for persistence - In-memory data is lost on plugin restart
  2. Cache frequently accessed data - Use sync.Map or similar for hot data
  3. Keep portal pages lightweight - Portal users expect fast page loads

WebComponent Patterns

  1. Wait for API injection - Use the waitForAPIAndLoad() pattern instead of calling the API in connectedCallback() directly
  2. Handle errors gracefully - Show user-friendly messages, not stack traces
  3. Use Shadow DOM - Prevents style conflicts with the host application
  4. Escape user content - Always escape HTML in dynamic content to prevent XSS