From 71ed2bd6774ed4cdca8ee4afaeee0fc2b02452c1 Mon Sep 17 00:00:00 2001 From: selul Date: Thu, 23 Apr 2026 13:46:12 +0300 Subject: [PATCH] feat(onboarding): support TI_ONBOARDING_DEFAULT_SITE redirect When the TI_ONBOARDING_DEFAULT_SITE constant is defined, the post-activation redirect now lands on the preview/import screen for that site (admin.php?page=neve-onboarding&site=) instead of the default search/welcome screen. The onboarding store resolves the ?site= query param against the bootstrapped sites list (across all builders) and starts at step 3 with currentSite preset; if the slug is unknown the app falls back to the existing search screen. This lets distributions and embedded environments (e.g. WordPress Playground) deep-link a user straight to the import flow for a chosen starter site. Made-with: Cursor --- includes/Admin.php | 19 ++++++++++--------- onboarding/src/store/reducer.js | 21 +++++++++++++++++++-- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/includes/Admin.php b/includes/Admin.php index ec4b873a..46e4aa21 100755 --- a/includes/Admin.php +++ b/includes/Admin.php @@ -398,15 +398,16 @@ public function activation_redirect() { } delete_option( 'tpc_maybe_run_onboarding' ); - wp_safe_redirect( - add_query_arg( - array( - 'page' => 'neve-onboarding', - 'show' => 'welcome', - ), - admin_url( 'admin.php' ) - ) - ); + + $query_args = array( 'page' => 'neve-onboarding' ); + + if ( defined( 'TI_ONBOARDING_DEFAULT_SITE' ) && TI_ONBOARDING_DEFAULT_SITE ) { + $query_args['site'] = sanitize_key( TI_ONBOARDING_DEFAULT_SITE ); + } else { + $query_args['show'] = 'welcome'; + } + + wp_safe_redirect( add_query_arg( $query_args, admin_url( 'admin.php' ) ) ); exit(); } diff --git a/onboarding/src/store/reducer.js b/onboarding/src/store/reducer.js index 051ac6cf..3c16f323 100644 --- a/onboarding/src/store/reducer.js +++ b/onboarding/src/store/reducer.js @@ -16,15 +16,32 @@ const initialLicense = licenseTIOB || { tier: 0, }; +const params = new URLSearchParams( window.location.search ); +const defaultSiteSlug = params.get( 'site' ); + +const findSiteBySlug = ( slug ) => { + const builders = onboarding?.sites?.sites || {}; + for ( const builder of Object.keys( builders ) ) { + if ( builders[ builder ]?.[ slug ] ) { + return builders[ builder ][ slug ]; + } + } + return null; +}; + +const defaultSite = defaultSiteSlug ? findSiteBySlug( defaultSiteSlug ) : null; + const initialState = { sites: onboarding.sites || {}, editor: selectedEditor, category: '', - currentSite: null, + currentSite: defaultSite, fetching: false, searchQuery: '', license: initialLicense, - onboardingStep: window.location.search.includes('show=welcome') ? 1 : 2, + onboardingStep: defaultSite + ? 3 + : ( window.location.search.includes('show=welcome') ? 1 : 2 ), userCustomSettings: { siteName: null, siteLogo: null,