OnboardingOverview

The onboarding system is designed to let you build a complete, production-ready onboarding flow without writing business logic or UI code. Everything is driven by a single configuration file, while the rendering, navigation, state management, and persistence are handled by the boilerplate.

The goal is simple: define what you want to ask the user, in which order, and how the answers are stored — the system takes care of the rest.

How the onboarding works

At a high level, the onboarding flow works like this:

  1. You define your onboarding steps in a config file
  2. The Onboarding component reads this config
  3. Each step is rendered using a predefined step component
  4. User answers are stored automatically in the global store
  5. When onboarding is completed, the app continues to the main flow

No navigation logic, no state wiring, no persistence code is required.

Where onboarding lives in the project

The onboarding feature is split into three clear parts:

1. Routing

The onboarding screens live inside a dedicated route group:

  • src/app/(onboarding)/

This allows the app to completely separate onboarding from the rest of the application (tabs, modals, main screens).

2. Configuration

The onboarding flow itself is defined in a single config file:

  • src/shared/config/onboarding.config.ts

This file describes:

  • The list of steps
  • Their order
  • Their type
  • How user data is stored

You will spend most of your time editing this file.

3. Rendering & logic

The rendering logic is already implemented for you:

  • src/features/onboarding
  • Built-in step components (welcome, select, text input, etc.)
  • A step renderer that maps step types to UI components
  • Automatic navigation, progress bar, and persistence

You never need to modify this unless you build custom steps.

Data flow and persistence

Each step stores its result using a property key defined in the config.

  • All onboarding answers are merged into a single userData object
  • Data is stored in a Zustand store
  • The store is persisted automatically
  • Data remains available after onboarding is completed

Example:

If a step uses:

  • property: "goal"

Then the answer will be available as:

  • userData.goal

This makes onboarding data immediately usable across the app.

What is configurable vs what is fixed

Configurable

  • Step order
  • Step types
  • Text, titles, descriptions
  • Options and inputs
  • Conditional display logic
  • Stored data keys
  • Custom steps

Fixed (by design)

  • Navigation behavior
  • State management
  • Persistence
  • Step transitions
  • Progress handling

This separation ensures consistency, speed, and safety while still allowing deep customization when needed.