8
Fullstack

Multi-Step Onboarding

A comprehensive, multi-step onboarding wizard component with form validation, progress tracking, and seamless Next.js server actions integration.

Multi-Step Onboarding Wizard

A powerful, accessible multi-step onboarding wizard that guides users through profile completion with real-time validation, progress indicators, and seamless Next.js server actions integration. Perfect for user registration, profile setup, and data collection workflows.

Multi-Step Onboarding Wizard Component
Loading component registry...

Installation

Install the component using the AxionsJS CLI:

npx axionjs-ui add multi-step-form

Configure your environment variables in .env:

# Database
DATABASE_URL="postgresql://username:password@localhost:5432/database_name"

# Next.js Configuration
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET="your-nextauth-secret"

Set up Prisma schema and push to database:

npx prisma db push

The component includes complete database models for user profiles, form validation schemas, and server actions. All forms are pre-configured with accessibility features and responsive design.

Database Schema

Add the following model to your schema.prisma file:

schema.prisma
model UserProfile {
  id                  String   @id @default(cuid())
  email               String   @unique
  name                String?
  bio                 String?  @db.Text
  avatarUrl           String?
  createdAt           DateTime @default(now())
  updatedAt           DateTime @updatedAt
  preferences         Json?
  completedOnboarding Boolean  @default(false)
 
  // Relations
  quizzes         Quiz[]
  quizSubmissions QuizSubmission[]
}

Run npx prisma db push after adding the schema to apply changes to your database.

Usage

Import and use the OnboardingWizard component:

app/onboarding/page.tsx
import { OnboardingWizard } from "@/components/onboarding-wizard";
 
export default function OnboardingPage() {
  return (
    <div className="container py-10">
      <h1 className="text-3xl font-bold text-center mb-8">
        Complete Your Profile
      </h1>
      <OnboardingWizard
        redirectUrl="/dashboard"
        showStepIndicator={true}
        submitButtonLabel="Complete Setup"
      />
    </div>
  );
}

Key Features

Component Props

PropTypeDefault
redirectUrl
string
"/dashboard"
className
string
""
initialStep
number
1
showStepIndicator
boolean
true
submitButtonLabel
string
"Complete Setup"
onComplete
(data: OnboardingFormValues) => void
undefined

Form Steps

The onboarding wizard consists of 4 comprehensive steps:

Step 1: Personal Information

  • Name (required, minimum 2 characters)
  • Bio (optional, maximum 500 characters)
  • Real-time validation with helpful error messages
components/personal-info-form.tsx
<FormField
  control={form.control}
  name="name"
  render={({ field }) => (
    <FormItem>
      <FormLabel>Full Name</FormLabel>
      <FormControl>
        <Input placeholder="Enter your full name" {...field} />
      </FormControl>
      <FormMessage />
    </FormItem>
  )}
/>

Server Actions

The component utilizes Next.js server actions for secure data persistence:

actions/multi-step-form-actions.ts
"use server";
 
import { revalidatePath } from "next/cache";
import type { OnboardingFormValues } from "@/components/onboarding-wizard";
import { db } from "@/lib/db";
 
export async function saveOnboardingData(data: OnboardingFormValues) {
  try {
    // Extract and structure user preferences
    const preferences = {
      theme: data.theme,
      emailFrequency: data.emailFrequency,
      marketingEmails: data.marketingEmails,
      notifications: {
        email: data.emailNotifications,
        push: data.pushNotifications,
        activitySummary: data.activitySummary,
        newFeatures: data.newFeatures,
        securityAlerts: data.securityAlerts,
      },
    };
 
    // Update user profile with upsert operation
    await db.userProfile.upsert({
      where: { id: userId },
      update: {
        name: data.name,
        bio: data.bio || null,
        avatarUrl: data.avatarUrl || null,
        preferences: preferences,
        completedOnboarding: true,
        updatedAt: new Date(),
      },
      create: {
        id: userId,
        email: "user@example.com", // From auth session
        name: data.name,
        bio: data.bio || null,
        avatarUrl: data.avatarUrl || null,
        preferences: preferences,
        completedOnboarding: true,
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    });
 
    revalidatePath("/dashboard");
    return { success: true };
  } catch (error) {
    console.error("Error saving onboarding data:", error);
    return { success: false, error: "Failed to save onboarding data" };
  }
}

Server Action Features:

  • Type-safe data handling with TypeScript
  • Upsert operations for flexible data management
  • Automatic path revalidation for fresh data
  • Comprehensive error handling and logging
  • Structured JSON preferences storage

Form Validation

The wizard uses Zod for comprehensive form validation:

components/onboarding-wizard.tsx
const formSchema = z.object({
  // Step 1: Personal Information
  name: z.string().min(2, { message: "Name must be at least 2 characters" }),
  bio: z
    .string()
    .max(500, { message: "Bio must not exceed 500 characters" })
    .optional(),
 
  // Step 2: Profile Picture
  avatarUrl: z.string().optional(),
 
  // Step 3: Preferences
  theme: z.enum(["light", "dark", "system"], {
    required_error: "Please select a theme preference",
  }),
  emailFrequency: z.enum(["daily", "weekly", "monthly", "never"], {
    required_error: "Please select an email frequency",
  }),
  marketingEmails: z.boolean().default(false),
 
  // Step 4: Notifications
  emailNotifications: z.boolean().default(true),
  pushNotifications: z.boolean().default(true),
  activitySummary: z.boolean().default(true),
  newFeatures: z.boolean().default(true),
  securityAlerts: z.boolean().default(true),
});

Validation Features:

  • Step-by-step validation prevents invalid progression
  • Real-time error messages with helpful guidance
  • Optional fields with smart defaults
  • Type-safe form data throughout the application

Accessibility Features

The Multi-Step Onboarding Wizard is built with accessibility in mind:

  • Keyboard Navigation: Full keyboard support with proper focus management
  • Screen Reader Support: ARIA labels, roles, and live regions
  • Progress Indicators: Clear step progression for assistive technologies
  • Form Validation: Accessible error messages and field descriptions
  • Focus Management: Automatic focus movement between steps
  • Skip Functionality: Optional steps can be skipped for better UX

The component follows WCAG 2.1 AA guidelines and has been tested with popular screen readers.

Conclusion

The Multi-Step Onboarding Wizard provides a complete, production-ready solution for user onboarding in Next.js applications. With its comprehensive form validation, accessibility features, and seamless server actions integration, it delivers an excellent user experience while maintaining robust data handling and security.

On this page