Skip to content
Back to archipelago.banuacoder.com

Feature SDKs

How to add an onboarding flow to a Flutter app ​

Free Reference for introduction_sdk: every variable, option and package it generates. Command: archipelago generate introduction_sdk

Generate the Introduction SDK, see how it claims the initial route, save completion so users see it once, and customize the pages.

What you'll learn ​

  • Generating the Introduction SDK with the onboarding flow
  • Understanding how it claims the initial route
  • Saving completion so users see the intro once
  • Customizing the pages

Prerequisites ​

The pages call AuthSDK.requireAuthentication() and HomeSDK.goToHome(). The brick does not generate these for you, so a standalone run leaves an unresolved workspace. flutter_modular_monorepo avoids this. It adds auth_sdk and home_sdk when you pick introduction_sdk in starterFeatures.

Step 1: Generate the Introduction SDK ​

bash
archipelago generate introduction_sdk

The prompts are:

  • appName: your app name, for example MyApp
  • prefix: the prefix for generated class names
  • uiKitPackageName: the UI kit package. It is read from archipelago.yaml.
  • isForMonorepo: leave this as true

Or use a config file:

json
{
  "appName": "MyApp",
  "isForMonorepo": true
}
bash
archipelago generate introduction_sdk --config intro_config.json

Step 2: Understand the Generated Structure ​

The brick makes one flat package. There is no _api and _impl split, because no other feature needs its contract.

text
features/introduction/
├── lib/src/
│   ├── introduction_sdk.dart            # IntroductionSDK and its implementation
│   ├── di/introduction_global_module.dart
│   ├── presentation/
│   │   ├── introduction_shell_page.dart
│   │   ├── welcome_page.dart
│   │   ├── features_page.dart
│   │   └── get_started_page.dart
│   └── router/introduction_router.dart
├── build.yaml
└── pubspec.yaml

Step 3: Check the Registration ​

The post-generation hook adds the package to the workspace and the app pubspec.yaml. It registers IntroductionGlobalModule in lib/di/injector.dart. You write no registration code.

The global module registers IntroductionManifest and IntroductionSDK as a lazy singleton. The manifest claims the initial path /introduction with priority 10:

dart
InitialPathClaim(
  priority: 10,
  resolve: () => isCompleted() ? null : '/introduction',
)

The pages read IntroductionSDK, AuthSDK and HomeSDK from an IntroductionScope widget in the shell page, not from GetIt. Priority 10 is checked first. Onboarding wins until it is completed. The claim reads isCompleted through a provider closure. The SDK is built when the router resolves the initial path.

Step 4: Save Completion ​

The brick keeps completion in memory only. As generated, users see onboarding on every cold start. Add persistence before you ship.

IntroductionSDKImpl has two TODO(user) comments, in initialize() and in markIntroductionCompleted(). Load and save the flag there, for example through storage_sdk. Take the storage by constructor and pass it from the global module.

Step 5: Complete or Skip the Intro ​

dart
final sdk = getIt<IntroductionSDK>();

if (!sdk.isCompleted) {
  await sdk.launch(context); // replaceAll to the introduction shell
}

sdk.markIntroductionCompleted();
sdk.skipIntroduction(); // calls markIntroductionCompleted()

Step 6: Customize the Pages ​

Replace the placeholder content in welcome_page.dart, features_page.dart and get_started_page.dart. Read tokens from context.colors, context.typography and context.spacing.

Common Customizations ​

CustomizationWhere to Change
Number of feature pagesfeatures_page.dart
Skip buttonwelcome_page.dart
Branding and assetsThe page files and your asset package
Completion storageIntroductionSDKImpl
Route priorityThe InitialPathClaim in the manifest

Next Steps ​