Multi-page intro flow using starter kit templates with customizable pages, dots, and callbacks
Onboarding provides a multi-page intro screen shown on first app launch. The starter kit provides ready-made templates (standard, minimal, custom) via StarterKit.onboarding().
starter-kit/SKILL.md)For simple onboarding, no separate feature folder is needed — use starter kit directly. For custom onboarding with business logic:
features/onboarding/
├── presentation/
│ ├── screens/
│ │ └── onboarding_screen.dart
│ └── widgets/
│ └── onboarding_page.dart
└── domain/
└── usecases/
└── complete_onboarding_usecase.dart # Saves "onboarding_done" flag
class OnboardingScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StarterKit.onboarding(
template: OnboardingTemplateType.standard,
pages: [
OnboardingPageModel(
title: 'Welcome',
description: 'Discover amazing features',
imagePath: 'assets/onboarding/welcome.png',
titleColor: Colors.blue,
),
OnboardingPageModel(
title: 'AI Powered',
description: 'Powered by cutting-edge AI',
imagePath: 'assets/onboarding/ai.png',
),
OnboardingPageModel(
title: 'Get Started',
description: 'Sign up and start exploring',
customWidget: MyCustomHeroWidget(),
),
],
onComplete: () {
// Save onboarding completion flag
SharedPreferences.getInstance().then((prefs) {
prefs.setBool('onboarding_complete', true);
});
Navigator.pushReplacementNamed(context, Routes.home);
},
onSkip: () {
Navigator.pushReplacementNamed(context, Routes.home);
},
activeDotColor: AppColors.primary,
nextText: 'Next',
completeText: 'Get Started',
);
}
}
// In splash screen
final prefs = await SharedPreferences.getInstance();
final onboardingDone = prefs.getBool('onboarding_complete') ?? false;
if (onboardingDone) {
Navigator.pushReplacementNamed(context, Routes.home);
} else {
Navigator.pushReplacementNamed(context, Routes.onboarding);
}
isFirstTimeUser() aligns with onboarding stateonboarding_started, onboarding_completed, onboarding_skippedStarterKit.onboarding() called with correct templateonComplete saves completion flag and navigatesonSkip handles skip properlyroutes_manager.dart