OOnboard v1.0.0
A self-hosted WordPress onboarding flow builder — 10 step types, conditional branching, A/B testing, drop-off analytics, and post-completion automation. Your data, your database, no SaaS fees.
What OOnboard does
Multi-step guided experiences for new users — from simple welcome screens to quiz-driven branching flows with registration gating, video steps, and post-completion automation. Self-hosted, WordPress-native, no monthly SaaS cost.
next_step_index{{user_name}}, {{site_name}}, and custom tags| Feature | OOnboard | UserGuiding | Appcues |
|---|---|---|---|
| Self-hosted | ✓ | ❌ SaaS | ❌ SaaS |
| WordPress-native | ✓ | — | — |
| Data stays in your DB | ✓ | — | — |
| Registration gating in-flow | ✓ | — | — |
| ORegister + OMailer integration | ✓ | — | — |
| Cost | One-time / annual | $89–249/mo | $249+/mo |
Getting installed
oonboard folder to /wp-content/plugins/ or install via WP Admin → Plugins → Add New → Upload.{prefix}oob_progress, {prefix}oob_events) and registers the oo_flow custom post type.Your first flow in minutes
[oonboard_trigger id="YOUR_FLOW_ID" label="Start"]Admin interface
Persistent two-row sticky header — brand bar (icon + name + version + light/dark toggle) plus a horizontal tab nav. Theme preference persisted to localStorage under key oob_theme.
Dashboard
Four-stat summary row — Total Flows, Flow Starts, Completions, Avg Completion Rate — followed by a table of recent flows with per-flow conversion stats.
Flows tab
Lists all flows with name, display style, trigger type, status pill (Active / Draft), start count, and completion rate. Actions: Edit (opens Builder), Duplicate, Delete. Live search filters flows by name.
Flow builder
| Panel | Contents |
|---|---|
| Left — Steps list | Ordered steps with index + type. + Add Step opens the type picker (10 types). Each row has Edit, Move Up, Move Down, Delete. |
| Right — Step Editor | Appears when editing a step. Common fields: Title, Content, Button Text, Skip Text. Type-specific fields appear below. |
| Right — Flow Settings | Always visible: Flow Name, Display Style, Progress Style, Trigger, Target Page ID, Allow Skip, Resume Position, Back Button, A/B Test, Post-Flow Actions (redirect, message, XP, OMailer, role, webhook). |
Progress tab
Paginated table of all user interactions. Filter by flow or status. Delete individual records with the trash icon.
| Column | Description |
|---|---|
| User | Display name + email, or "Guest" for anonymous users |
| Flow | Flow name |
| Variant | A or B (for A/B tests) |
| Status | started completed abandoned |
| Step | Current step number |
| Timestamps | Started at / Completed at |
Analytics tab
Per-flow analysis. Select a flow from the dropdown to see stats.
| Component | Description |
|---|---|
| Stats row | Total Starts, Completions, Completion Rate, Avg Completion Time |
| Daily Completions chart | Canvas bar chart — daily completions over last 30 days |
| Step Drop-Off table | Per-step view counts and abandonment percentage |
| A/B Test Results | Side-by-side cards for Variant A and B; "Winner" badge on the higher completion rate |
Global settings
| Setting | Description |
|---|---|
| Default Display Style | Applied to new flows; can be overridden per flow |
| Disable for admins | Auto-trigger flows won't fire for WordPress admin users |
| Load assets globally | Enqueue frontend CSS/JS on all pages — needed for manual trigger buttons in headers/footers |
| Default OMailer List ID | Default list for post-flow OMailer subscriptions |
| ORegister XP event key | The event key sent to ORegister on flow completion |
The Settings tab also shows a Merge Tags Reference and Shortcode Reference panel in-admin.
Ten step types
auto_advance when video ends via API.user_meta.wp_create_user().all_required gate before advancing.next_step_index per option for conditional branching paths.redirect_delay seconds.Four display styles
Set per-flow in Flow Settings. Can also be overridden by the style attribute on the trigger shortcode.
Progress indicators
| Type | Description |
|---|---|
bar | Thin accent-colored progress bar at the top of the flow card |
steps | "Step 2 / 5" text label |
dots | Row of clickable dots, one per step |
percent | Percentage text — e.g. "40%" |
none | No progress indicator shown |
Flow triggers
| Trigger | When it fires |
|---|---|
| Manual | Only when the user clicks a [oonboard_trigger] button or OOBFrontend.launchFlow() is called |
| First Login | Hooks into wp_login. Queues the flow after the first login and auto-launches it on the next page load. |
| Page Load | Auto-launches when a user visits the configured Target Page ID. Excludes anonymous users and already-completed users. |
| Time-Based | Reserved for Pro — trigger N days after the user's registration date. |
Conditional branching
Implemented via the Quiz step type. Each answer option has a next_step_index field that overrides the default sequential next step.
When a user selects an option, OOB_Engine::ajax_complete_step() reads the chosen option's next_step_index and jumps there instead of current_index + 1. If next_step_index is null, the flow advances normally.
Merge tags
Double-brace {{placeholders}} replaced at render time by OOB_Merge_Tags::process(). Work in step title, content, and subheading fields.
| Tag | Replaced with |
|---|---|
| {{user_name}} | User's display name — "there" for guests |
| {{user_first}} | User's first name |
| {{user_last}} | User's last name |
| {{user_email}} | User's email address |
| {{site_name}} | WordPress site name |
| {{site_url}} | WordPress home URL |
| {{current_date}} | Today's date (WordPress date format) |
| {{current_year}} | Current year (4 digits) |
| {{admin_email}} | Admin email address |
Custom merge tags
PHPadd_filter('oob_merge_tag_context', function($context, $flow_id, $user_id) {
$context['custom']['plan_name'] = 'Pro';
return $context;
}, 10, 3);
// Now use {{plan_name}} in any step field
Post-flow actions
Run automatically when a user completes the final step, via OOB_Actions::run(). Configure in Builder → Flow Settings.
| Action | Description |
|---|---|
| Redirect URL | Redirect the user's browser to a specified URL |
| Success Message | Display a custom message on the completion screen |
| Award XP | Calls oregister_award_xp($user_id, $amount, $event_key) — requires ORegister |
| Award Badge ID | Calls oregister_award_badge($user_id, $badge_id) — requires ORegister |
| OMailer List ID | Subscribes user to an OMailer list via om_subscribe() — requires OMailer |
| Assign WP Role | Changes the user's WordPress role on completion |
| Webhook URL | Sends a POST request with a JSON payload to an external URL |
| Webhook Secret | HMAC-SHA256 signs the payload — header: X-OOnboard-Signature |
JSON · webhook payload{
"event": "flow_completed",
"flow_id": 42,
"user_id": 7,
"time": 1745625600
}
A/B testing
Enable per-flow in Builder → Flow Settings → A/B Test checkbox. New users are randomly assigned 50/50 to Variant A (original steps) or Variant B (separate step set).
| Detail | Value |
|---|---|
| Variant assignment | Random 50/50 for new users. Stored in {prefix}oob_progress.variant — users always see the same variant. |
| Variant B steps | Stored in _oob_variant_b post meta. A "Variant B" step list appears in the builder when A/B testing is enabled. |
| Results | Analytics tab → A/B Test Results section. Side-by-side starts, completions, completion rate. "Winner" badge on the higher-performing variant. |
Shortcodes
[oonboard id="X"]
Embeds a flow inline on any page or post in Embedded display style.
[oonboard id="42"]
| Attribute | Required | Description |
|---|---|---|
id | Yes | Flow post ID |
[oonboard_trigger id="X" label="Start"]
Renders a styled button that launches a flow when clicked.
[oonboard_trigger id="42" label="Start the Tour" style="modal"]
| Attribute | Default | Description |
|---|---|---|
id | — | Flow post ID (required) |
label | Start | Button text |
style | modal | modal, full-page, slide-in, embedded |
class | — | Additional CSS classes for the button element |
Gutenberg block
OOnboard registers an OOnboard Flow block in the Gutenberg editor under the Widgets category.
OOB_Shortcode::render_embed() at display time. In the editor it shows a preview card with the flow name and ID.Orravo integrations
oregister_award_xp() and oregister_award_badge() on flow completion. XP event key configurable in Settings. ORegister must be installed and active.om_subscribe() with first_name, last_name, list_id, and source on completion. OMailer must be installed and active.PHP · OMailer callom_subscribe( $user_email, [
'first_name' => $user->first_name,
'last_name' => $user->last_name,
'list_id' => $list_id,
'source' => 'oonboard',
] );
Developer API
PHP helper functions
PHP// Check if the current user has completed a flow
oob_has_completed_flow( int $flow_id, int $user_id = 0 ): bool
// Get the admin builder URL for a flow
oob_get_flow_url( int $flow_id ): string
OOB_Flow — flow CRUD
PHPOOB_Flow::create( string $name, array $settings = [] ): int
OOB_Flow::update( int $id, array $data ): bool
OOB_Flow::delete( int $id ): bool
OOB_Flow::duplicate( int $id ): int
OOB_Flow::get( int $id ): ?WP_Post
OOB_Flow::get_all( array $args = [] ): array
OOB_Flow::get_steps( int $id ): array
OOB_Flow::get_settings( int $id ): array
OOB_Flow::get_post_actions( int $id ): array
OOB_Progress — progress tracking
PHPOOB_Progress::upsert( int $flow_id, int $user_id, string $session_key ): int
OOB_Progress::update_step( int $flow_id, int $step_index, int $user_id, string $session_key ): void
OOB_Progress::complete( int $flow_id, int $user_id, string $session_key ): void
OOB_Progress::abandon( int $flow_id, int $user_id, string $session_key ): void
OOB_Progress::has_completed( int $flow_id, int $user_id ): bool
OOB_Progress::log_event( int $flow_id, string $event, int $step_index, ... ): void
OOB_Analytics
PHPOOB_Analytics::get_flow_stats( int $flow_id ): array
OOB_Analytics::get_dashboard_totals(): array
OOB_Analytics::get_dropoff_by_step( int $flow_id ): array
OOB_Analytics::get_ab_stats( int $flow_id ): array
OOB_Merge_Tags
PHPOOB_Merge_Tags::process( string $content, array $context = [] ): string
OOB_Merge_Tags::get_available_tags(): array
JavaScript API
JS// Programmatically launch a flow
OOBFrontend.launchFlow( flowId, displayStyle );
// Close a running flow
OOBFrontend.closeFlow( flowId );
Database schema
oob_progress
| Column | Type | Description |
|---|---|---|
id | BIGINT UNSIGNED | Primary key |
user_id | BIGINT UNSIGNED | WordPress user ID — 0 for guests |
flow_id | BIGINT UNSIGNED | Post ID of the oo_flow CPT |
variant | VARCHAR(8) | A or B (A/B tests) |
step_index | SMALLINT | Current step the user is on |
status | VARCHAR(20) | started, completed, or abandoned |
session_key | VARCHAR(64) | PHP session key for guest users |
started_at | DATETIME | UTC timestamp of flow start |
updated_at | DATETIME | UTC timestamp of last update |
completed_at | DATETIME | UTC timestamp of completion (NULL if incomplete) |
Indexes: (user_id, flow_id), (flow_id, status)
oob_events
| Column | Type | Description |
|---|---|---|
id | BIGINT UNSIGNED | Primary key |
user_id | BIGINT UNSIGNED | WordPress user ID |
flow_id | BIGINT UNSIGNED | Flow post ID |
step_index | SMALLINT | Step the event occurred on |
event_type | VARCHAR(30) | start, step_view, step_complete, complete, skip, abandon |
variant | VARCHAR(8) | A/B variant |
session_key | VARCHAR(64) | Guest session key |
created_at | DATETIME | UTC event timestamp |
Indexes: (flow_id, event_type, created_at), (flow_id, step_index, event_type)
Custom post type: oo_flow
| Meta key | Type | Description |
|---|---|---|
_oob_steps | JSON | Array of step objects |
_oob_settings | JSON | Flow settings object |
_oob_post_actions | JSON | Post-completion action settings |
_oob_variant_b | JSON | Array of step objects for Variant B |
AJAX endpoints
All endpoints registered via wp_ajax_* hooks and require a valid nonce.
Frontend endpoints (public + logged-in)
| Action | Method | Description |
|---|---|---|
oob_get_flow_init | POST | Get flow metadata and resume index. Params: flow_id |
oob_get_step | POST | Fetch a step's rendered data. Params: flow_id, step_index |
oob_complete_step | POST | Mark step complete, get next step index. Params: flow_id, step_index, quiz_answer (opt), form_data (opt) |
oob_skip_step | POST | Skip a step, advance to next |
oob_abandon_flow | POST | Mark flow as abandoned |
Admin endpoints (requires manage_options)
| Action | Description |
|---|---|
oob_create_flow | Create a new flow |
oob_save_flow | Save steps, settings, and post-actions |
oob_delete_flow | Delete a flow |
oob_duplicate_flow | Duplicate a flow |
oob_save_settings | Save global plugin settings |
oob_get_flow_data | Get full flow data as JSON |
oob_delete_progress | Delete a progress record by ID |
Hooks & filters
Actions
| Hook | Arguments | Description |
|---|---|---|
oob_flow_completed | $flow_id, $user_id, $actions | Fired when a user completes a flow |
oob_flow_started | $flow_id, $user_id | Available for custom extension on flow start |
PHPadd_action('oob_flow_completed', function($flow_id, $user_id, $actions) {
if ($flow_id === 42) {
update_user_meta($user_id, 'onboarding_complete', '1');
}
}, 10, 3);
Filters
| Filter | Arguments | Description |
|---|---|---|
oob_merge_tag_context | $context, $flow_id, $user_id | Add custom merge tag values to the context |
oob_step_html | $html, $step, $flow_id | Filter the rendered HTML of any step |
oob_flow_settings | $settings, $flow_id | Filter flow settings before they're used |
Frequently asked questions
{prefix}oob_progress with user_id = 0 and a session_key.OOB_Progress::reset($flow_id, $user_id) programmatically, or provide a restart button using [oonboard_trigger].[oonboard] shortcodes or trigger buttons on the same page.OOB_DB::uninstall() drops the {prefix}oob_progress and {prefix}oob_events tables, deletes all oo_flow posts, and removes OOnboard options. This is permanent.DELETE FROM {prefix}oob_events WHERE flow_id = X and DELETE FROM {prefix}oob_progress WHERE flow_id = X directly in your database.variant column of {prefix}oob_progress. Once assigned, they always see the same variant. New users are randomly assigned 50/50.oob_flow_completed action hook alongside WooCommerce's own hooks — for example, triggering a welcome flow after a first purchase.What's shipped
- Flow builder admin with 10 step types
- Full-page, modal, slide-in, and embedded display styles
- Progress bar, step numbers, dots, and percentage indicators
- Conditional branching via quiz step
next_step_index - Resume from last position
- Auto-launch triggers: first login, page load
- User progress table with status and step tracking
- Drop-off analysis per step with color coding
- Daily completions chart (30-day canvas)
- A/B flow testing with variant assignment and comparison
- Post-flow actions: redirect, success message, role, XP, badge, OMailer, webhook
- HMAC-SHA256 signed webhooks
- Merge tags:
{{user_name}},{{site_name}}, etc. - Shortcodes:
[oonboard id],[oonboard_trigger id] - Gutenberg block with server-side rendering
- ORegister and OMailer integration hooks
- Dark/light admin theme with token system
- Complete uninstall hook — removes all data
oob_flow_completedaction hook for developer extensibility
Got a question about OOnboard?
Reach out directly — Kenneth replies within 24 hours.
