NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages
Onboarding for Laravel

Extending & exceptions

Flow, Step and OnboardingManager all use Laravel’s Macroable trait, so you can add fluent helpers at boot without subclassing:

use RoundlyConsulting\Onboarding\Flow;
use RoundlyConsulting\Onboarding\OnboardingManager;
use RoundlyConsulting\Onboarding\Step;

// e.g. in a service provider's boot()
Step::macro('completeWhenVerified', fn () => $this->completeWhenTrue('email_verified_at'));
Flow::macro('progressLabel', fn () => round($this->percentageCompleted()).'% done');
OnboardingManager::macro('keys', fn () => $this->all()->keys());
Step::make('Verify email')->completeWhenVerified();

$user->onboarding()?->progressLabel();   // "67% done"
Onboarding::keys();                      // Collection of registered flow keys

Other extension points

  • Custom flow classes — extend Flow and configure it in setup().
  • The resolver — Onboarding::resolveUsing() picks a flow per subject.
  • defaultOnboardingKey() — override it on a model to choose its flow.
  • The OnboardingStore contract — plug in your own with Onboarding::useStore() for dismissible steps and once-only events.
  • Events — listen to StepCompleted and FlowCompleted to persist progress or trigger side effects.

Exceptions

ExceptionExtendsThrown when
OnboardingExceptionInvalidArgumentExceptionBase type for the package’s exceptions.
InvalidFlowException::keyMustBeString()OnboardingExceptionregister() received a non-string key together with a flow.
InvalidFlowException::notAFlowClass($class)OnboardingExceptionA class string that is not Flow or a subclass was registered.
InvalidStoreException::notAStore($class)OnboardingExceptionuseStore() received a class that doesn’t implement OnboardingStore.
use RoundlyConsulting\Onboarding\Exceptions\InvalidFlowException;
use RoundlyConsulting\Onboarding\Facades\Onboarding;

try {
    Onboarding::register(SomeNonFlowClass::class);
} catch (InvalidFlowException $e) {
    // "[App\SomeNonFlowClass] is not a RoundlyConsulting\Onboarding\Flow class."
}

OnboardingException extends InvalidArgumentException, so existing catch (InvalidArgumentException) blocks keep working.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.