Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Onboarding Laravel Package

guava/onboarding

Guava Onboarding provides a Laravel-friendly foundation for building user onboarding flows, with structured steps and a simple API to guide new users through setup. Add configurable onboarding journeys to your app without building the plumbing from scratch.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer and publish the package assets:

composer require guava/onboarding
php artisan vendor:publish --tag="onboarding-migrations"
php artisan migrate

The first place to look is the HasOnboarding trait — this is what plugs the package into any Eloquent model (typically User, but also Team or Company). Add it to the model that should go through onboarding:

use Guava\Onboarding\Concerns\HasOnboarding;

class User extends Authenticatable
{
    use HasOnboarding;
}

Next, define your first step. A step is any class implementing the OnboardingStep contract. The trait gives you $user->onboardings(), $user->onboardingSteps(), and helpers like $user->isOnboarded() / $user->markStepAsCompleted(...). Your first realistic use case is a "welcome checklist" for new signups: define 3–5 steps (e.g. VerifyEmailStep, CreateFirstProjectStep, InviteTeammateStep), render them in a page, and gate each step's action behind the step's action() callback. If you also need an admin-facing onboarding builder, the adjacent Filament plugin is the second thing to install — see the Filament notes below.

Implementation Patterns

Step classes as the primary unit of work. Keep each onboarding step in app/Onboarding/Steps/. A step defines key(), title(), description(), action() (the URL or callback that advances it), and optionally condition() and dependencies(). Treating steps as classes (not array config) is what makes them testable and lets you inject services via the container.

Dependency chaining. Use dependencies() to declare ordering without hardcoding a sequence. This lets you render the same step list in multiple places (dashboard card, dedicated onboarding page, notification) and have the package resolve what's actionable. Prefer this over a manually curated sort column — the dependency graph is what powers nextStep().

Programmatic completion. For server-side events (webhook received, first API call), call $user->completeOnboardingStep(VerifyEmailStep::class) inside the relevant event listener rather than relying on the UI button. This keeps onboarding state consistent whether the user clicks through or the system advances them.

Filament integration. Register the plugin in your panel provider (->plugin(OnboardingPlugin::make())). Since 2.2.1 is the version that fixes Filament v5 compatibility, pin guava/onboarding to ^2.2 if your panel is on Filament v5 — earlier 2.2.0 installs can break on the resource registration. The plugin exposes an admin UI for tracking completion rates, which is genuinely useful for product teams; use it read-only unless you deliberately want admins to complete steps on behalf of users.

Scoping to multiple entities. Because the trait is model-agnostic, a common pattern is to apply onboarding to both User and Team. Steps should either be entity-agnostic or accept the entity type in condition() so you don't force the same checklist on both.

Gotchas and Tips

  • Filament v5 requires 2.2.1+. The only fix in this release is Filament v5 compatibility, so on v5 you must be on 2.2.1 or later. If your panel boots but the onboarding resource fails to register, this is almost certainly the cause.
  • Migration conflicts on multi-entity setups. The default migrations target a polymorphic onboardable reference. If you're onboarding both User and Team, verify the polymorphic index exists before relying on morphTo queries at scale.
  • condition() is evaluated at render time, not cached. Don't put expensive queries in a condition — it runs on every step-list render. Memoize on the model instance if needed.
  • Re-completion is not idempotent by default. Calling completeOnboardingStep() twice creates duplicate completion rows unless you guard with a wasCompleted() check or the once config. Wrap completion in a small domain service if the triggering action can fire twice (retries, double-clicks, webhook replays).
  • Debugging: $user->onboardingSteps() returns the resolved step objects with their current completion state — dump this when a step "isn't showing." The usual culprits are a failing condition(), an unmet dependencies() entry, or a step key collision across flows.
  • Extension points: publish the config (php artisan vendor:publish --tag="onboarding-config") to override the storage model and table names before adding your own fields; extending the completion model after migration is painful. If you need custom persistence (e.g. append-only event sourcing), subclass the provided model rather than reimplementing the trait.
  • Keep step keys stable. Keys are persisted; renaming a step key orphans completions. Add a data migration if you must rename, and consider treating the class name as the stable identifier via completeOnboardingStep(StepClass::class).
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums