New-Company Onboarding
Audience: Sales · Support · QA · Engineering · Management · Where in app: /onboarding (auto-redirected for new web-owners) · Plan availability: All plans (runs before/around subscription)
Onboarding is the full-screen wizard a brand-new company is forced through before they reach the main dashboard. It collects account details, scans their website, trains the AI agent, lets them review the generated agent, then walks them through customizing the widget, setting call routing, trying a playground, and finally installing the widget snippet on their site. Progress is saved per-step on the company record so users can leave and resume — and can even start on mobile and finish on desktop via an emailed magic link.
What it does
- Forces setup for new web-owners. The router redirects any
web_ownerwhoseuser.onboarding_completedis false to/onboarding(router/index.js). - Walks an ordered list of steps, persisting completion per step (
company.onboarding_steps[]). - Resumes intelligently: with no
?stepin the URL it jumps to the step after the last completed one; if all are done it lands on the first config sub-step. - Adapts to screen size: a mobile-only "complete" step hands the user off to desktop to finish widget install.
- Finishes by stamping
onboarding_completedon both the user and company and routing to the dashboard.
How it works
The wizard shell is onboarding/index.vue; step order and visibility live in the Pinia store store/onboarding.js (ALL_ONBOARDING_STEPS). The current step is derived from ?step=<n> in the URL, kept in sync via browser back/forward.
Steps (in order)
| ID | Label | In progress bar? | Component | Purpose |
|---|---|---|---|---|
account | Account | Yes | steps/AccountStep.vue | Name, company name, phone, password, timezone. Skipped on load if already complete (see below). |
website | Website | Yes | steps/WebsiteStep.vue | Connect/scan the company website to seed AI knowledge. |
training | Training | No | steps/TrainingStep.vue | Trains the AI agent (driven by its own CTA, hidden from the progress bar). |
industry | Industry | Yes | steps/IndustryStep.vue | Pick the business type (uses helpers/industryTemplates.js). |
details | Details | Yes | steps/DetailsStep.vue | Business details that feed the agent's persona. |
review | Review | Yes | steps/ReviewStep.vue | "Meet {agent}. It's ready" — review the generated agent personality/flow. |
mobile-complete | Complete | No (mobile only) | steps/MobileCompleteStep.vue | Mobile success screen; hands off to desktop. |
config_widget | Customize Widget | No | ConfigurationScreen.vue | Widget appearance/layout. |
config_routing | Call Routing | No | ConfigurationScreen.vue | Call handling/routing defaults. |
config_playground | Playground | No | ConfigurationScreen.vue | Try the widget live in a sandbox. |
install | Install | No | InstallScreen.vue | Copy the widget snippet / email it to a developer; finish. |
The three config_* steps share one component (ConfigurationScreen.vue); it derives which section to render from the current step ID, and the same component reference is reused across the three keys so Vue keeps it mounted between them (no re-mount flicker).
Progress bar vs hidden steps
The horizontal stepper only shows steps with showInProgressBar: true (progressBarSteps): Account, Website, Industry, Details, Review. training, all config_*, install, and mobile-complete are hidden and driven by their own screens' CTAs.
Account-step skip
On load, the store snapshots whether account info is already complete (captureAccountStepState). "Complete" means: first name, company name, phone number, a set password (or social login), and the company timezone is not still the backend default (Pacific/Auckland) when the user's system timezone differs. If complete at load, the account step is removed from activeSteps for the whole session (the snapshot prevents the step from vanishing mid-session after the user saves it).
Install screen
InstallScreen.vue shows the embed snippet:
<script>
// Knock Knock Widget
window.company_id = '<company._id>'
var newScript = document.createElement('script')
newScript.src = '<API_URL>/widget/widget.js'
document.getElementsByTagName('HEAD')[0].appendChild(newScript)
</script>
From here the user can:
- Copy Code to the clipboard.
- Email to Developer — opens a modal, collects developer emails (
FormMultipleEmails), and posts the install email viaPOST /email-send/<company._id>. The email body is white-label aware (omits thehello@knockknockapp.aisupport line for white-labeled companies). - Email Me Setup Link (mobile) — sends the same instructions to the signed-in user so they can continue on desktop; shows a "what to do next" magic-link modal.
- Go to Dashboard — calls
finishOnboarding().
It notes the snippet can always be retrieved later under Settings → Widget → Installation.
Finishing
finishOnboarding() (store):
PUT /user/<id>{ onboarding_completed: true }PUT /company/<id>{ onboarding_completed: true }- Optional auto-trial: if a
registered_package_id(orlocalStorage register_pkg) resolves to a package withaffiliate_program && trial_without_card && free_trial === 'yes', it creates a trial subscription (POST /subscription,trial: true), reloads the subscription + company, and clears the local register keys. - Toasts "Setup complete!" and routes to
dashboard— always landing on the dashboard so users can explore.
Configuration & options
What gets written, and where:
| Step | Persisted to | Mechanism |
|---|---|---|
| Per-step completion | company.onboarding_steps[] | POST /company/complete-onboarding-step (completeStep) |
| Step data (account/industry/details/config) | company.* | PUT /company/<id> with the step payload, then complete-onboarding-step |
| Final completion | user.onboarding_completed, company.onboarding_completed | PUT /user/<id>, PUT /company/<id> |
| Install email | (email only — no DB write) | POST /email-send/<company._id> |
skipStep(stepId) marks a step complete with an empty payload (no data saved) — used where a step can be passed without input.
Behaviors & edge cases
- Resume after leaving: with no
?step, the store resumes at the step after the last completed one; if everything is complete it opensconfig_widget. - Browser back/forward: each step
pushes a history entry (updateUrlWithStep), andindex.vuewatchesroute.query.stepto re-sync. - Mobile→desktop handoff:
mobile-completeismobileOnly. On desktop,findNextValidStepIndexskips it; on mobile it's shown and routes users to email themselves the desktop magic link. - Theme + logout are available in the onboarding header; the header/progress bar are hidden on the full-viewport
config_*andinstallsteps (showInProgressBar === false). - White-label branding: logo, name, store links, and email copy resolve through
useAppBranding/appStore.brandingName(agency name first). White-labeled flows must not surface the Knock Knock support address. - Router exit guard: once
user.onboarding_completedis true, the router prevents bouncing back into/onboarding(seerouter/index.js).
Plan & limits
Onboarding runs for all new web-owner accounts regardless of plan. The only plan-adjacent behavior is the auto-trial branch in finishOnboarding (affiliate packages with card-free trials). Exact package eligibility is data-driven (the package record's affiliate_program/trial_without_card/free_trial flags) — confirm specifics with billing/product (verify).
Technical implementation
- Shell view:
frontend/src/views/onboarding/index.vue - Step components:
frontend/src/views/onboarding/steps/*(Account, Website, Training, Industry, Details, Review, MobileComplete) - Shared config screen:
frontend/src/views/onboarding/ConfigurationScreen.vue - Install screen:
frontend/src/views/onboarding/InstallScreen.vue - Supporting components:
onboarding/components/*(Playground*, StepNavigation, DynamicField, MobileStepHeader) - Helpers:
onboarding/helpers/industryTemplates.js,masterVoiceTemplate.js - Store:
frontend/src/store/onboarding.js(ALL_ONBOARDING_STEPS,completeStep,skipStep,finishOnboarding, URL sync) - Route: name
onboarding, path/onboarding(auth required, onboarding check skipped); redirect logic infrontend/src/router/index.js - Backend:
POST /company/complete-onboarding-step,PUT /company/<id>,PUT /user/<id>,POST /subscription,POST /email-send/<id>. See services/backend.
Related
- Quick Start and Platform Overview.
- Widget Installation — the snippet shown on the install step, retrievable later in Settings → Widget.
- Settings → Working Hours and Settings → Call Preferences — refine what onboarding's config steps seed.
- Free Tier & Trials — the auto-trial path triggered at finish (verify path).
- services/frontend · services/backend.