Skip to Content
Dial v1 live 🎉
BeaconConfig Reference

Config Reference

Complete reference for the Beacon V1 configuration schema. All fields are validated with Zod at runtime.

Top-Level Schema

{ version: 1, // Always 1 projectId: string, // Your project ID env: "prod" | "staging", // Environment (default: "prod") configMode: "remote" | "local", // Config fetch mode (default: "remote") branding: BrandingConfig, placement: PlacementConfig, triggers: TriggersConfig, lanes: LanesConfig, quickActions: QuickAction[], // Max 5 actions verify: VerifyConfig, handoff: HandoffConfig, faq: FaqConfig, analytics: AnalyticsConfig, }

Branding

{ branding: { name: string, // Display name (default: "Support") accentColor?: string, // Primary color shorthand logoUrl?: string, // URL to logo image theme?: { accentColor?: string, // Primary brand color backgroundColor?: string, // Panel background textColor?: string, // Primary text textSecondaryColor?: string, // Secondary/muted text borderColor?: string, // Borders and dividers borderRadius?: number, // 0-24 pixels fontFamily?: string, // CSS font-family } } }

Placement

{ placement: { position: "bottom-right" | "bottom-left", // Default: "bottom-right" zIndex?: number, // Custom z-index } }

Triggers

{ triggers: { autoOpen?: { enabled: boolean, // Default: false delayMs?: number, // Milliseconds before auto-open paths?: string[], // URL paths (supports regex) exitIntent?: boolean, // Open on exit intent } } }

Lanes

{ lanes: { support: { enabled: boolean, // Default: true label: string, // Default: "Support" description?: string, }, sales: { enabled: boolean, // Default: false label: string, // Default: "Sales" description?: string, }, community: { enabled: boolean, // Default: false label: string, // Default: "Community" description?: string, } } }

Quick Actions

Discriminated union on the type field:

open_chat

{ id: string, label: string, icon?: string, lane: "support" | "sales" | "community", type: "open_chat" }

book_call

{ id: string, label: string, icon?: string, lane: "sales", type: "book_call" }

join_room

{ id: string, label: string, icon?: string, lane: "community", type: "join_room", roomId: string }
{ id: string, label: string, icon?: string, lane: "support" | "sales" | "community", type: "open_link", url: string // Must be a valid URL }

verify_then

{ id: string, label: string, icon?: string, type: "verify_then", nextActionId: string // ID of the action to execute after verification }

Verify

{ verify: { enabled: boolean, // Default: false provider: "dial", // Only "dial" supported gates: { [gateId: string]: { required: boolean, scopes?: string[], // e.g., ["wallet", "role:holder"] onSuccessActionId?: string, } } } }

Handoff

{ handoff: { emailCapture?: { enabled: boolean, // Default: false to: string, // Valid email address }, calendar?: { enabled: boolean, // Default: false url: string, // Valid URL }, externalLinks?: Array<{ label: string, url: string, // Valid URL }> } }

FAQ

{ faq: { enabled: boolean, // Default: false items: Array<{ q: string, // Question a: string, // Answer url?: string, // Optional "Learn more" URL }> } }

Analytics

{ analytics: { enabled: boolean, // Default: true endpoint: string, // Default: "https://api.dial.wtf/v1/beacon/events" sampleRate: number, // 0-1, default: 1 } }

Validation

Config is validated using Zod at runtime. Invalid configs are rejected with descriptive error messages logged to the console. Default values are applied for optional fields — you only need to specify what you want to customize.

import { parseBeaconConfig, safeParseBeaconConfig } from '@dial-beacon/core'; // Throws on invalid config const config = parseBeaconConfig(rawConfig); // Returns { success, data, error } const result = safeParseBeaconConfig(rawConfig); if (result.success) { console.log(result.data); } else { console.error(result.error); }
Last updated on