Guides / SaaS

How to Track User Onboarding Completion

4 min read·SaaS

Why onboarding tracking matters

Most SaaS churn happens before users ever experience value. If you don't track onboarding steps, you can't see where users abandon the flow.

Define your steps

First, map out your onboarding steps and give them numeric IDs:

ts
// lib/onboarding.ts
export const ONBOARDING_STEPS = {
  ACCOUNT_CREATED: 1,
  PROFILE_COMPLETED: 2,
  FIRST_PROJECT_CREATED: 3,
  SDK_INSTALLED: 4,
  FIRST_EVENT_LOGGED: 5,
  TEAM_INVITED: 6,
} as const;

type OnboardingStep = keyof typeof ONBOARDING_STEPS;

Track each step

ts
import { logit } from "@/lib/logit";

export async function trackOnboardingStep(
  userId: string,
  step: OnboardingStep,
  metadata?: Record<string, string | number>
) {
  const stepNumber = ONBOARDING_STEPS[step];

  await logit.now("onboarding", {
    event: `Onboarding step ${stepNumber}: ${step.replace(/_/g, " ").toLowerCase()}`,
    description: `User ${userId} completed step ${stepNumber}/${Object.keys(ONBOARDING_STEPS).length}`,
    icon: stepNumber === Object.keys(ONBOARDING_STEPS).length ? "🎉" : "✅",
    notify: step === "FIRST_EVENT_LOGGED",
    tags: { step: String(stepNumber), stepName: step },
    metadata: { userId, step, stepNumber, ...metadata },
  });
}

Track abandonment (the hard part)

ts
// Run this via a cron job: every day, check users who signed up 3 days ago but haven't completed step 3+
async function checkAbandonedOnboarding() {
  const cutoff = new Date(Date.now() - 3 * 24 * 60 * 60 * 1000);
  const stuckUsers = await db.user.findMany({
    where: {
      createdAt: { lt: cutoff },
      onboardingStep: { lt: 3 },
    },
    take: 100,
  });

  for (const user of stuckUsers) {
    await logit.now("onboarding-abandoned", {
      event: "User stuck in onboarding",
      description: `Stuck at step ${user.onboardingStep} for 3+ days`,
      icon: "⚠️",
      notify: false,
      metadata: { userId: user.id, step: user.onboardingStep, email: user.email },
    });
  }
}

Completion funnel

With this setup, your LogIt dashboard shows:

  • onboarding channel: step-by-step progress per user
  • onboarding-abandoned channel: who is stuck and where
  • Filter by stepName tag to see exact drop-off counts

Try LogIt free

7-day trial. No credit card required.

Start free