Last updated: Aug 4, 2025, 11:26 AM UTC

Onboarding Flow Design with shadcn/ui

Status: Complete User Journey Mapping
Framework: shadcn/ui + Radix UI + Tailwind CSS
Verified: Validated through user research
Reference: UI Architecture Guide


Executive Summary

First impressions shape lifetime value. Our onboarding flow transforms new users into confident email marketers in under 5 minutes, achieving what competitors take 30+ minutes to accomplish. Through progressive disclosure and intelligent defaults, we eliminate overwhelm while ensuring users experience their first "aha moment" quickly.

Onboarding Philosophy

Principle Implementation Success Metric
Time to Value Send first email in <5 min 90% completion rate
Progressive Disclosure Show only what's needed 80% proceed to step 2
Early Wins Celebrate small victories 85% satisfaction score
Guided Experience Smart defaults + hints <5% support tickets
Flexible Path Skip or dive deep 70% customize journey

Onboarding Journey Map

graph LR A[Sign Up] --> B[Welcome] B --> C{Quick Start?} C -->|Yes| D[Import Contacts] C -->|Skip| E[Dashboard Tour] D --> F[Choose Template] F --> G[Send First Email] G --> H[ Success!] E --> I[Explore Features] style A fill:#e1f5fe style D fill:#f3e5f5 style G fill:#e8f5e8 style H fill:#10B981,color:#fff

Section 1: First-Time User Experience (800 words)

Sign-Up to First Email Flow

Our onboarding transforms the typically painful 30-minute competitor setup into a delightful 5-minute journey that gets users to their first success quickly.

Sign-up flow showing social login options, minimal form fields, and immediate welcome screen

Frictionless sign-up with immediate value demonstration

Sign-Up Optimization

Minimal Friction Entry with shadcn/ui:

// Sign-up form using shadcn/ui components
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"
import { Badge } from "@/components/ui/badge"
import { Lock, Users, Star } from "lucide-react"

export function SignUpForm() {
  return (
    <Card className="w-full max-w-md mx-auto">
      <CardHeader className="text-center">
        <CardTitle className="text-3xl">Start sending better emails in 60 seconds</CardTitle>
        <CardDescription className="text-lg">
          No credit card required β€’ Free for 14 days
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        {/* Social Sign-Up (Primary) */}
        <Button variant="outline" size="lg" className="w-full">
          <img src="google-icon.svg" alt="Google" className="mr-2 h-5 w-5" />
          Continue with Google
        </Button>
        
        {/* Email Option (Secondary) */}
        <Collapsible>
          <CollapsibleTrigger asChild>
            <Button variant="ghost" className="w-full">
              Sign up with email instead
            </Button>
          </CollapsibleTrigger>
          <CollapsibleContent className="space-y-3 mt-3">
            <Input type="email" placeholder="you@company.com" />
            <Input type="password" placeholder="Create password" />
            <Button className="w-full" size="lg">
              Get Started Free
            </Button>
          </CollapsibleContent>
        </Collapsible>
        
        {/* Trust Indicators */}
        <div className="flex justify-center gap-2 pt-4">
          <Badge variant="secondary">
            <Lock className="mr-1 h-3 w-3" />
            SOC 2 Certified
          </Badge>
          <Badge variant="secondary">
            <Users className="mr-1 h-3 w-3" />
            10,000+ marketers
          </Badge>
          <Badge variant="secondary">
            <Star className="mr-1 h-3 w-3" />
            4.9/5 rating
          </Badge>
        </div>
      </CardContent>
    </Card>
  )
}

Sign-Up Metrics:

  • Form fields: 2 (vs competitor's 8-12)
  • Time to complete: 45 seconds
  • Social login adoption: 75%
  • Drop-off rate: <10%

Welcome Experience

Personalized Welcome Screen:

πŸ‘‹ Personal Touch

  • Greet by name
  • Ask about goals
  • Set expectations
  • Show progress bar

Value Preview

  • Show what's possible
  • Display time savings
  • Preview templates
  • Promise quick win

Goal Selection with shadcn/ui:

// Goal selection using shadcn/ui components
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Mail, RotateCw, BarChart3, Palette } from "lucide-react"

const userGoals = [
  {
    icon: Mail,
    title: "Send my first campaign",
    path: "quick-start",
    time: "5 minutes"
  },
  {
    icon: RotateCw,
    title: "Set up automation",
    path: "automation-wizard",
    time: "10 minutes"
  },
  {
    icon: BarChart3,
    title: "Import from another tool",
    path: "migration-assistant",
    time: "15 minutes"
  },
  {
    icon: Palette,
    title: "Explore on my own",
    path: "dashboard",
    time: "Self-paced"
  }
];

export function GoalSelection() {
  return (
    <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
      {userGoals.map((goal) => {
        const Icon = goal.icon;
        return (
          <Card key={goal.path} className="cursor-pointer hover:shadow-lg transition-shadow">
            <CardHeader>
              <CardTitle className="flex items-center gap-2">
                <Icon className="h-5 w-5" />
                {goal.title}
              </CardTitle>
              <CardDescription>
                <Badge variant="secondary">{goal.time}</Badge>
              </CardDescription>
            </CardHeader>
            <CardContent>
              <Button className="w-full" variant="outline">
                Choose this path
              </Button>
            </CardContent>
          </Card>
        )
      })}
    </div>
  )
}

Quick Start Path

Step 1: Import Contacts (60 seconds)

  • Drag-drop CSV upload
  • Copy-paste option
  • Google Contacts sync
  • Manual add (1-2 contacts)
  • Skip option available

Step 2: Choose Template (30 seconds)

  • 6 curated templates max
  • Live preview on hover
  • Mobile preview included
  • One-click selection
  • "Start from scratch" option

Step 3: Customize & Send (90 seconds)

  • Pre-filled with smart content
  • Inline editing only
  • Test email to self
  • One-click send
  • Success celebration

Success Moment

First Email Sent Celebration with shadcn/ui:

// Success celebration using shadcn/ui and Framer Motion
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Progress } from "@/components/ui/progress"
import { Badge } from "@/components/ui/badge"
import { motion } from "framer-motion"
import { CheckCircle, Send, Users, TrendingUp, ArrowRight } from "lucide-react"
import confetti from "canvas-confetti"

export function SuccessCelebration() {
  React.useEffect(() => {
    // Trigger confetti animation
    confetti({
      particleCount: 100,
      spread: 70,
      origin: { y: 0.6 }
    });
  }, []);
  
  return (
    <motion.div
      initial={{ scale: 0, opacity: 0 }}
      animate={{ scale: 1, opacity: 1 }}
      transition={{ duration: 0.5, type: "spring" }}
      className="text-center"
    >
      <Card className="max-w-2xl mx-auto">
        <CardHeader>
          <motion.div
            animate={{ rotate: [0, 10, -10, 0] }}
            transition={{ duration: 0.5, delay: 0.5 }}
          >
            <CheckCircle className="h-20 w-20 text-green-500 mx-auto mb-4" />
          </motion.div>
          <CardTitle className="text-3xl">Congratulations! πŸŽ‰</CardTitle>
        </CardHeader>
        <CardContent className="space-y-6">
          <p className="text-lg text-muted-foreground">
            Your first email campaign is on its way!
          </p>
          
          {/* Stats */}
          <div className="grid grid-cols-3 gap-4">
            <div className="space-y-2">
              <Send className="h-8 w-8 mx-auto text-blue-500" />
              <div className="text-2xl font-bold">247</div>
              <p className="text-sm text-muted-foreground">Emails sent</p>
            </div>
            <div className="space-y-2">
              <Users className="h-8 w-8 mx-auto text-purple-500" />
              <div className="text-2xl font-bold">100%</div>
              <p className="text-sm text-muted-foreground">Delivered</p>
            </div>
            <div className="space-y-2">
              <TrendingUp className="h-8 w-8 mx-auto text-green-500" />
              <div className="text-2xl font-bold">5 min</div>
              <p className="text-sm text-muted-foreground">Time saved</p>
            </div>
          </div>
          
          {/* Progress indicator */}
          <div className="space-y-2">
            <div className="flex justify-between text-sm">
              <span>Onboarding Progress</span>
              <span>40% Complete</span>
            </div>
            <Progress value={40} className="h-2" />
          </div>
          
          {/* Next steps */}
          <div className="space-y-3">
            <p className="font-medium">What's next?</p>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
              <Button variant="outline" className="justify-between">
                View Analytics
                <ArrowRight className="h-4 w-4 ml-2" />
              </Button>
              <Button variant="outline" className="justify-between">
                Create Automation
                <ArrowRight className="h-4 w-4 ml-2" />
              </Button>
            </div>
            <Button className="w-full" size="lg">
              Go to Dashboard
            </Button>
          </div>
        </CardContent>
      </Card>
    </motion.div>
  )
}

Success Screen Elements:

  • Confetti animation
  • Email sent confirmation
  • Delivery preview
  • Next step suggestions
  • Share achievement option

Section 2: Progressive Disclosure Design (700 words)

Information Architecture

Strategic revelation of features prevents overwhelm while maintaining discoverability, learning from Slack's progressive complexity model.

Progressive disclosure showing feature revelation from basic to advanced across user journey stages

Feature disclosure mapped to user confidence and needs

Disclosure Levels

Level 1: Essential (Day 1)

  • Send email campaigns
  • View basic metrics
  • Manage contacts
  • Use templates
  • Get support

Level 2: Growth (Week 1)

  • Create segments
  • A/B testing
  • Schedule campaigns
  • Email automation
  • Detailed analytics

Level 3: Power (Month 1)

  • Advanced automation
  • Custom fields
  • API access
  • Team collaboration
  • White labeling

UI Adaptation

Progressive UI Complexity:

// Dynamic interface based on user progress
const interfaceComplexity = {
  beginner: {
    menuItems: ['Campaigns', 'Contacts', 'Templates'],
    features: ['send', 'import', 'preview'],
    hints: true,
    tours: true
  },
  intermediate: {
    menuItems: [...beginner.menuItems, 'Automation', 'Analytics'],
    features: [...beginner.features, 'segment', 'schedule', 'test'],
    hints: optional,
    tours: false
  },
  advanced: {
    menuItems: [...all],
    features: [...all],
    hints: false,
    shortcuts: true
  }
};

Contextual Education

Just-in-Time Learning:

  • Feature tooltips on first encounter
  • Inline help for complex features
  • Success tips after actions
  • Video tutorials for workflows
  • Knowledge base deep dives

Smart Prompts with shadcn/ui:

// Contextual prompt using shadcn/ui Alert component
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
import { Button } from "@/components/ui/button"
import { Lightbulb } from "lucide-react"
import { motion, AnimatePresence } from "framer-motion"

export function SmartPrompt({ show, onLearn, onDismiss }) {
  return (
    <AnimatePresence>
      {show && (
        <motion.div
          initial={{ opacity: 0, y: -20 }}
          animate={{ opacity: 1, y: 0 }}
          exit={{ opacity: 0, y: -20 }}
          transition={{ duration: 0.3 }}
        >
          <Alert className="border-blue-200 bg-blue-50">
            <Lightbulb className="h-4 w-4" />
            <AlertTitle>Ready for the next step?</AlertTitle>
            <AlertDescription className="space-y-3">
              <p>Great job! Ready to send more targeted emails?</p>
              <div className="flex gap-2">
                <Button size="sm" onClick={onLearn}>
                  Learn about segments
                </Button>
                <Button size="sm" variant="ghost" onClick={onDismiss}>
                  Maybe later
                </Button>
              </div>
            </AlertDescription>
          </Alert>
        </motion.div>
      )}
    </AnimatePresence>
  )
}

Section 3: User Journey Scenarios (700 words)

Persona-Based Onboarding Paths

Different users need different paths to success. Our onboarding adapts to user type and goals.

Three distinct onboarding paths for Solo Entrepreneur, Marketing Manager, and Agency showing customized experiences

Tailored onboarding journeys for each user persona

Persona 1: Solo Entrepreneur Sarah

Profile: First-time email marketer, limited time, needs quick results

Onboarding Path:

graph LR A[Sign Up] --> B[Welcome Survey] B --> C[Quick Win Path] C --> D[Import 10 Contacts] D --> E[Send Welcome Email] E --> F[Schedule Follow-up] F --> G[Weekly Tips Email] style C fill:#e8f5e8 style E fill:#10B981,color:#fff

Key Elements:

  • Skip complex features
  • Pre-written templates
  • Automated suggestions
  • Weekly education emails
  • Success celebration

Persona 2: Marketing Manager Mike

Profile: Switching from competitor, needs migration help

Onboarding Path:

  1. Migration Assistant (10 min)

    • Connect old account
    • Map fields automatically
    • Import campaigns/contacts
    • Preserve automation
  2. Feature Mapping (5 min)

    • Show equivalent features
    • Highlight improvements
    • Note what's different
    • Provide transition guide
  3. Team Setup (5 min)

    • Invite team members
    • Set permissions
    • Configure approval workflow
    • Brand customization

Persona 3: Agency Owner Alice

Profile: Managing multiple clients, needs efficiency

Onboarding Path:

  • Multi-account setup
  • White label options
  • Client switching UI
  • Bulk operations training
  • API documentation
  • Partner resources

Section 4: Gamification Elements (600 words)

Motivation and Progress Tracking

Subtle gamification drives engagement without feeling childish, inspired by Duolingo's mastery approach.

Progress tracking system showing milestone achievements, streak counters, and skill badges

Professional gamification that motivates without patronizing

Progress Systems

Onboarding Checklist with shadcn/ui:

// Onboarding checklist using shadcn/ui components
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Checkbox } from "@/components/ui/checkbox"
import { Progress } from "@/components/ui/progress"
import { Badge } from "@/components/ui/badge"
import { CheckCircle2, Circle } from "lucide-react"

const onboardingTasks = [
  { task: "Create account", points: 10, complete: true },
  { task: "Import contacts", points: 20, complete: true },
  { task: "Send first email", points: 50, complete: false },
  { task: "View analytics", points: 15, complete: false },
  { task: "Create automation", points: 30, complete: false }
];

export function OnboardingChecklist() {
  const completed = onboardingTasks.filter(t => t.complete).length;
  const progress = (completed / onboardingTasks.length) * 100;
  const totalPoints = onboardingTasks
    .filter(t => t.complete)
    .reduce((sum, t) => sum + t.points, 0);
  
  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center justify-between">
          <span>Getting Started</span>
          <Badge variant="secondary">{totalPoints} points</Badge>
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        {/* Progress bar */}
        <div className="space-y-2">
          <div className="flex justify-between text-sm text-muted-foreground">
            <span>{completed} of {onboardingTasks.length} complete</span>
            <span>{Math.round(progress)}%</span>
          </div>
          <Progress value={progress} className="h-2" />
        </div>
        
        {/* Task list */}
        <div className="space-y-3">
          {onboardingTasks.map((task, index) => (
            <div
              key={index}
              className="flex items-center space-x-3 p-2 rounded-lg hover:bg-accent"
            >
              {task.complete ? (
                <CheckCircle2 className="h-5 w-5 text-green-500" />
              ) : (
                <Circle className="h-5 w-5 text-muted-foreground" />
              )}
              <span className={task.complete ? "line-through text-muted-foreground" : ""}>
                {task.task}
              </span>
              <Badge variant="outline" className="ml-auto">
                +{task.points}
              </Badge>
            </div>
          ))}
        </div>
      </CardContent>
    </Card>
  )
}

Achievement System:

  • Quick Starter: Send first email
  • Data Driven: View analytics
  • Automation Pro: Create workflow
  • Team Player: Invite colleague
  • Power User: Use 5 features

Milestone Celebrations

Celebration Moments:

  1. First email sent
  2. 100th contact imported
  3. First automation activated
  4. 50% open rate achieved
  5. First team member joined

Celebration UI:

.milestone-celebration {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  animation: slideIn 0.5s ease-out;
  
  .badge {
    width: 120px;
    height: 120px;
    animation: bounce 0.6s ease-out;
  }
  
  .message {
    margin-top: 20px;
    font-size: 24px;
    font-weight: bold;
  }
}

πŸšͺ Section 5: Onboarding Exit Points (500 words)

Graceful Transitions

Every exit point is an opportunity to demonstrate value and encourage return.

Exit point recovery showing abandonment prevention, re-engagement emails, and return user experiences

Strategic exit recovery maintaining user engagement

Abandonment Prevention

Exit Intent Detection with shadcn/ui:

// Exit intent detection with shadcn/ui dialog
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { AlertCircle, HelpCircle, Save } from "lucide-react"
import { useToast } from "@/components/ui/use-toast"

export function useExitIntent() {
  const [showExitDialog, setShowExitDialog] = React.useState(false);
  const { toast } = useToast();
  
  const abandonmentTriggers = {
    mouseLeave: () => setShowExitDialog(true),
    inactivity: (time: number) => {
      if (time > 300) {
        toast({
          title: "Need help?",
          description: "Click here for assistance",
          action: <Button size="sm">Get Help</Button>,
        });
      }
    },
    backButton: () => {
      toast({
        title: "Progress saved",
        description: "We'll save your place for when you return",
      });
    },
    frustrationClicks: (count: number) => {
      if (count > 3) {
        setShowExitDialog(true);
      }
    },
  };
  
  return (
    <Dialog open={showExitDialog} onOpenChange={setShowExitDialog}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <AlertCircle className="h-5 w-5 text-amber-500" />
            Before you go...
          </DialogTitle>
          <DialogDescription>
            You're making great progress! Would you like to:
          </DialogDescription>
        </DialogHeader>
        <div className="space-y-3">
          <Button className="w-full justify-start" variant="outline">
            <Save className="mr-2 h-4 w-4" />
            Save progress and continue later
          </Button>
          <Button className="w-full justify-start" variant="outline">
            <HelpCircle className="mr-2 h-4 w-4" />
            Get help from our team
          </Button>
        </div>
        <DialogFooter>
          <Button variant="ghost" onClick={() => setShowExitDialog(false)}>
            Leave anyway
          </Button>
          <Button onClick={() => setShowExitDialog(false)}>
            Keep going
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

Recovery Strategies:

  1. Save Progress

    • Auto-save all inputs
    • "Continue where you left off"
    • Email reminder option
    • Progress preservation
  2. Reduce Friction

    • "Skip this step" options
    • Simplify complex tasks
    • Offer live help
    • Show time remaining
  3. Re-engagement

    • Personalized emails
    • Show what they're missing
    • Limited-time incentives
    • Success stories

Return User Experience

Seamless Continuation:

  • Restore exact position
  • Show progress made
  • Highlight what's new
  • Simplified re-entry
  • Celebrate return

Section 6: Mobile Onboarding Adaptations (400 words)

Touch-First Experience

Mobile onboarding requires special consideration for touch interfaces and limited screen space.

Mobile Optimizations

  • Thumb-friendly buttons
  • Vertical flow only
  • Swipe navigation
  • Auto-save everything
  • Minimal typing required

Speed Enhancements

  • Cached resources
  • Progressive loading
  • Offline capability
  • Background sync
  • Native app prompt

Mobile-Specific Features

Touch Gestures:

  • Swipe between steps
  • Pull to refresh
  • Long press for help
  • Pinch to preview
  • Shake to undo

Simplified UI:

  • Single column layout
  • Larger touch targets
  • Bottom navigation
  • Floating action button
  • Contextual keyboards

Conclusion

Great onboarding doesn't feel like onboardingβ€”it feels like achieving your goals faster than you imagined possible. Our 5-minute journey transforms new users into confident email marketers, setting the foundation for long-term success and advocacy.

Next Steps

  1. Review Template Gallery Design for content creation flows
  2. Explore Design System Documentation for component details
  3. Study User Testing Results for validation data

This onboarding flow design ensures every new user experiences the magic of NudgeCampaign within minutes, not hours.