Skip to main content

OnboardingPortal

A full-screen, multi-step onboarding wizard that guides new accounts through business setup, phone number configuration, and hardware assignment.

Basic Usage

import { DialstackComponentsProvider } from '@dialstack/sdk';
import { OnboardingPortal } from '@dialstack/sdk/react/onboarding';

function OnboardingPage({ dialstack, clientSecret }) {
return (
<DialstackComponentsProvider dialstack={dialstack} clientSecret={clientSecret}>
<OnboardingPortal />
</DialstackComponentsProvider>
);
}
Separate Import Path

The OnboardingPortal is imported from @dialstack/sdk/react/onboarding, not from the main @dialstack/sdk entry point. This keeps the onboarding bundle separate from the lighter-weight components.

Automatic Progress Saving

The portal automatically saves onboarding progress to the server. Users can leave and return at any time — the wizard resumes where they left off.

How It Works

The onboarding portal presents three main steps, each with its own substeps:

StepDescriptionSubsteps
AccountBusiness profile and team setupBusiness Details, Team Members
NumbersPhone number ordering and portingNumber options, ordering/porting flow, primary number, caller ID, directory listing
HardwareDevice assignment for team membersDevice Assignment

The portal has three view modes that users progress through:

  1. Splash screen — a welcome screen shown on first visit
  2. Overview — a dashboard showing progress across all steps with status indicators
  3. Wizard — the step-by-step form workflow

When all steps are complete, a celebration screen is shown. After that, the overview screen serves as the landing page where users can review or revise any step.

Props

PropTypeDefaultDescription
localeLocaleEnglishCustom locale for UI strings
formattingFormattingOptions-Date/phone formatting options
iconsComponentIcons-Custom SVG icons
collectionOptionsOnboardingCollectionOptions-Control which steps to show
theme'light' | 'dark''light'Color theme
appearance{ variables?: { colorPrimary?: string; colorPrimaryHover?: string } }-Brand color overrides
logoHtmlstring-HTML string for sidebar logo
platformNamestring-Platform name shown in the UI
onBack() => void-Back button callback (shows button when provided)
backLabelstring-Label for the back button
fullTermsOfServiceUrlstring-Link to full terms of service
recipientTermsOfServiceUrlstring-Link to recipient terms of service
privacyPolicyUrlstring-Link to privacy policy
documentationUrlstring-Link shown on the overview screen
onScheduleCall() => void-Callback for "Schedule a Call" on the overview screen
onHelpSupport() => void-Callback for "Help & Support" in the sidebar
onStepChange(event: { step: AccountOnboardingStep }) => void-Called when the active step changes
classNamestring-Additional CSS class for the root element
styleReact.CSSProperties-Inline styles for the root element

Controlling Steps

Use collectionOptions to show or hide specific steps. The final completion screen is always shown regardless of these options.

Show only specific steps

<OnboardingPortal
collectionOptions={{
steps: {
include: ['account', 'numbers'],
},
}}
/>

Exclude specific steps

<OnboardingPortal
collectionOptions={{
steps: {
exclude: ['hardware'],
},
}}
/>

OnboardingCollectionOptions

OptionTypeDescription
steps.includeAccountOnboardingStep[]Show only these steps
steps.excludeAccountOnboardingStep[]Hide these steps

When both include and exclude are set, include is applied first, then exclude removes from that result.

AccountOnboardingStep

The available step values are:

ValueDescription
'account'Business details and team members
'numbers'Phone number ordering, porting, and configuration
'hardware'Device assignment
'final_complete'Completion screen (always shown)

White-Labeling

Customize the portal's branding to match your platform:

<OnboardingPortal
platformName="Acme Telecom"
logoHtml={`
<div style="display:flex;align-items:center;gap:8px">
<img src="/logo.svg" width="28" height="24" alt="" />
<span style="font-size:20px;font-weight:700;color:#f0f0ff">
Acme Telecom
</span>
</div>
`}
appearance={{
variables: {
colorPrimary: '#00A67E',
colorPrimaryHover: '#008F6D',
},
}}
/>

The appearance.variables colors are applied to the sidebar, buttons, and accent elements throughout the wizard. When not provided, the portal uses the colors set via initialize().

Dark Theme

<OnboardingPortal theme="dark" />

The theme can also be set globally via the appearance.theme option in initialize(). The component-level theme prop takes precedence.

onBack

Provide an onBack callback to show a back button in the sidebar. Use this to let users navigate back to your application:

<OnboardingPortal onBack={() => router.push('/dashboard')} backLabel="Back to Dashboard" />

onStepChange

Track which step the user is on:

<OnboardingPortal
onStepChange={(event) => {
analytics.track('onboarding_step', { step: event.step });
}}
/>

Help and Support

The overview screen and sidebar can link to help resources:

<OnboardingPortal
documentationUrl="https://docs.example.com/onboarding"
onScheduleCall={() => {
window.open('https://calendly.com/example/onboarding', '_blank');
}}
onHelpSupport={() => {
window.Intercom('showNewMessage', 'I need help with onboarding');
}}
/>
  • documentationUrl — shows a "View Documentation" link on the overview screen
  • onScheduleCall — shows a "Schedule a Call" button on the overview screen
  • onHelpSupport — shows a "Help & Support" link in the sidebar

Display terms and privacy links on the completion screen:

<OnboardingPortal
fullTermsOfServiceUrl="https://example.com/terms"
recipientTermsOfServiceUrl="https://example.com/recipient-terms"
privacyPolicyUrl="https://example.com/privacy"
/>

Complete Example

import { initialize, DialstackComponentsProvider } from '@dialstack/sdk';
import { OnboardingPortal } from '@dialstack/sdk/react/onboarding';
import { useEffect, useState } from 'react';

const dialstack = initialize({
publishableKey: 'pk_live_YOUR_KEY',
appearance: {
theme: 'light',
},
});

function OnboardingApp() {
const [clientSecret, setClientSecret] = useState<string | null>(null);

useEffect(() => {
fetch('/api/dialstack/session', { method: 'POST' })
.then((res) => res.json())
.then((data) => setClientSecret(data.client_secret));
}, []);

if (!clientSecret) return <div>Loading...</div>;

return (
<DialstackComponentsProvider dialstack={dialstack} clientSecret={clientSecret}>
<OnboardingPortal
platformName="Acme Telecom"
logoHtml={`
<div style="display:flex;align-items:center;gap:8px">
<img src="/logo.svg" width="28" height="24" alt="" />
<span style="font-size:20px;font-weight:700;color:#f0f0ff">
Acme Telecom
</span>
</div>
`}
appearance={{
variables: {
colorPrimary: '#6772E5',
colorPrimaryHover: '#5469D4',
},
}}
collectionOptions={{
steps: { exclude: ['hardware'] },
}}
onBack={() => (window.location.href = '/dashboard')}
backLabel="Back to Dashboard"
documentationUrl="https://docs.example.com/setup"
onScheduleCall={() => window.open('https://calendly.com/example')}
onHelpSupport={() => window.Intercom?.('show')}
onStepChange={(event) => {
console.log('Step changed:', event.step);
}}
fullTermsOfServiceUrl="https://example.com/terms"
privacyPolicyUrl="https://example.com/privacy"
/>
</DialstackComponentsProvider>
);
}

Next Steps