Skip to main content
Version: v1 (Current)

Portal Architecture

What is a Portal?

A portal is the attendee-facing web experience for a project. Each project can have multiple portals, each with its own custom domain, authentication configuration, pages, widgets, and theme. Portals are how attendees interact with the event — they never see the admin dashboard.

Portals are assembled from plugins: pages provide the content, widgets add global functionality, and themes control the look and feel. Project admins configure all of this through the dashboard.

Portal Hierarchy

Project
└── Portal (attendee.example.com)
├── Pages
│ ├── /register → Registration Form
│ ├── /schedule → Schedule Plugin (v3)
│ ├── /speakers → Speaker Directory Plugin (v2)
│ └── /social → Social Feed Plugin (v1)
├── Widgets
│ ├── Analytics Tracker (head script)
│ ├── Chat Widget (floating overlay)
│ └── Cookie Consent (banner)
├── Theme
│ ├── Public template (login, registration)
│ ├── Private template (authenticated pages)
│ └── Styles (CSS, branding)
└── Domains
├── conference.example.com (primary)
└── register.example.com (redirect → /register)

A single project can have multiple portals — for example, a main attendee portal and a separate VIP portal with different pages and authentication requirements.

Custom Domains

Every portal is served on one or more custom domains. The platform supports two domain types:

TypeFormatScopeExample
Wildcard*.customer.comTeam-level, shared across projectsevent1.customer.com, event2.customer.com
Singleapp.customer.comProject-level, one portal at a timeregister.myevent.com

How Domain Resolution Works

  1. Attendee's browser resolves the custom domain to the platform's load balancer
  2. The platform extracts the hostname from the request
  3. Looks up the ProjectPortalDomain record by hostname (cached for 60 seconds)
  4. Loads the parent portal with all its configuration, pages, and widgets
  5. If the domain has a redirect configured, issues a 302 redirect immediately

All custom domains CNAME to a single target, and SSL certificates are automatically provisioned and renewed via GCP Certificate Manager.

Authentication

Portals support 10 authentication methods, each configurable per-portal:

MethodDescription
Email/PasswordStandard email + password login
Phone/PasswordPhone number + password login
Magic LinkAuto-send magic link on email entry
One-Time PasswordOTP delivered via email or SMS
Link LoginMagic link sent via email or phone
SSO (SAML2)Enterprise single sign-on
Badge ScanQR code or barcode badge scan
Kiosk LoginLogin code for kiosk devices
Reader Access CodeAccess code for reader devices (kiosks, print servers)
Reader OTPOTP for reader devices

Each method can be independently enabled, ordered, and configured per-portal. Methods also support:

  • Group-based access control — restrict methods to specific attendee groups (e.g., SSO only for VIPs)
  • Inline registration — display a registration form alongside the login method
  • Post-auth redirects — send attendees to a specific page after login

Access Codes

Portals have a two-level access code system:

  • Portal-level codes — gate the entire portal; attendees must enter a code before seeing any page
  • Page-level codes — gate individual pages independently of the portal-level code

Access codes are stored as bcrypt hashes and verified via the session.

How a Portal Loads

When an attendee visits a portal, the request flows through several layers:

1. Domain resolves to portal

2. Portal configuration loaded (cached)

3. Access code check (portal-level)

4. Team context set (multi-tenant isolation)

5. Session timeout check

6. Page controller resolves content

7. Theme applies layout templates + styles

8. Navigation renders from portal pages

9. Page loads its plugin content (or form)

10. Widgets inject globally (scripts, overlays)

11. Inertia response sent to Vue 3 SPA

The result is a fully rendered page with the portal's theme, the plugin page's content, and all widgets active.

Pages

Portal pages are polymorphic — they can render two types of content:

Plugin Pages (Apps)

The primary content type. A ProjectPortalPage points to a ProjectPage, which references a PluginPage pinned to a specific version. The version contains the HTML template, CSS, JavaScript, and a dependency manifest.

Plugin content is rendered in a sandboxed context with the portal's theme, settings, and authenticated user data injected as props.

Forms

Registration forms, quizzes, and standard forms can also be served as portal pages. The system detects the form type and renders the appropriate component.

Page Properties

Each portal page carries:

PropertyPurpose
url_slugURL path (e.g., /schedule, /register)
titleDisplay title in portal navigation
sort_orderNavigation ordering
requires_authenticationWhether the page requires login
access_code_enabledWhether the page requires an access code
permission_flagsPermission checks for attendee access
plain_text_keySanctum token for API authorization (auto-generated)

API Authorization

Each page gets its own Sanctum token, auto-generated when the page is created. This token is passed to the plugin frontend as apiPageAuthId and included in all API calls via the X-Portal-Page-Token header. The token ties API access to the page's declared permissions — plugins can only access data their version explicitly declares in its dependencies.

Widgets

Widgets are persistent UI elements that appear on every portal page. They're designed for global functionality that isn't tied to a specific page.

Common widget types:

  • Head scripts — analytics trackers, tag managers
  • Floating overlays — chat bubbles, help buttons, notification bells
  • Banners — cookie consent, announcements
  • Footer components — persistent navigation, branding

Each widget:

  • References a PluginWidget pinned to a specific version
  • Has its own Sanctum token (independent of page tokens)
  • Carries custom settings, security overrides (CORS/iframe whitelist), and trigger state (show/hide conditions)

Widget data is resolved and shared to the frontend on every portal request.

Themes

Themes control the overall layout and styling of a portal. A PluginTheme provides:

  • Public template — layout for unauthenticated pages (login, registration)
  • Private template — layout for authenticated pages
  • System template — layout for system pages (error pages, access code entry)
  • Styles — CSS and JavaScript libraries that apply globally
  • Branding — colors, fonts, and visual identity settings

Themes are versioned like other plugins. Projects pin to a specific theme version.

Dashboard Tiles

Tiles are admin-side analytics displays — custom data visualizations that appear on the project dashboard. Unlike pages and widgets (which are attendee-facing), tiles are for project administrators.

A PluginTile provides versioned templates for rendering project data as charts, tables, counters, or other visualizations.

Settings Hierarchy

Configuration flows through a merge hierarchy where more specific settings override broader defaults:

Plugin Version Defaults (set by developer)
└── overridden by → Project Instance Settings (set by admin)
└── overridden by → Portal/Page-Level Settings (set by admin)

This applies to:

  • Settings — behavioral configuration
  • Styles — CSS overrides
  • Language strings — i18n translations

Plugin developers set sensible defaults; project admins customize for their event.

Next Steps