diff --git a/projects/packages/my-jetpack/_inc/components/welcome-flow/ConnectionStep.tsx b/projects/packages/my-jetpack/_inc/components/welcome-flow/ConnectionStep.tsx
index fe727a0702d9a..358260fce50a4 100644
--- a/projects/packages/my-jetpack/_inc/components/welcome-flow/ConnectionStep.tsx
+++ b/projects/packages/my-jetpack/_inc/components/welcome-flow/ConnectionStep.tsx
@@ -1,13 +1,18 @@
import { Col, Button, Text, TermsOfService } from '@automattic/jetpack-components';
+import { initializeExPlat, loadExperimentAssignment } from '@automattic/jetpack-explat';
import { __ } from '@wordpress/i18n';
import { useCallback, useContext } from 'react';
import { NoticeContext } from '../../context/notices/noticeContext';
import { NOTICE_SITE_CONNECTED } from '../../context/notices/noticeTemplates';
import useAnalytics from '../../hooks/use-analytics';
+import sideloadTracks from '../../utils/side-load-tracks';
import styles from './style.module.scss';
+import { WelcomeFlowExperiment } from '.';
+import type { Dispatch, SetStateAction } from 'react';
type ConnectionStepProps = {
onActivateSite: ( e?: Event ) => Promise< void >;
+ onUpdateWelcomeFlowExperiment: Dispatch< SetStateAction< WelcomeFlowExperiment > >;
isActivating: boolean;
};
@@ -16,23 +21,52 @@ type ConnectionStepProps = {
*
* @param {object} props - ConnectioStepProps
* @param {Function} props.onActivateSite - Alias for handleRegisterSite
+ * @param {Function} props.onUpdateWelcomeFlowExperiment - Updating the welcomeFlowExperiment state
* @param {boolean} props.isActivating - Alias for siteIsRegistering
* @returns {object} The ConnectionStep component.
*/
-const ConnectionStep = ( { onActivateSite, isActivating }: ConnectionStepProps ) => {
+const ConnectionStep = ( {
+ onActivateSite,
+ onUpdateWelcomeFlowExperiment,
+ isActivating,
+}: ConnectionStepProps ) => {
const { recordEvent } = useAnalytics();
const { setNotice, resetNotice } = useContext( NoticeContext );
const activationButtonLabel = __( 'Activate Jetpack in one click', 'jetpack-my-jetpack' );
- const onConnectSiteClick = useCallback( () => {
+ const onConnectSiteClick = useCallback( async () => {
recordEvent( 'jetpack_myjetpack_welcome_banner_connect_site_click' );
- onActivateSite().then( () => {
- recordEvent( 'jetpack_myjetpack_welcome_banner_connect_site_success' );
+ onUpdateWelcomeFlowExperiment( state => ( { ...state, isLoading: true } ) );
+ await onActivateSite();
+
+ recordEvent( 'jetpack_myjetpack_welcome_banner_connect_site_success' );
+
+ try {
+ await sideloadTracks();
+
+ initializeExPlat();
+
+ const { variationName } = await loadExperimentAssignment(
+ 'jetpack_my_jetpack_post_connection_flow_202408'
+ );
+
+ if ( variationName !== 'treatment' ) {
+ // For control or default, we redirect to the connection page as described in the experiment.
+ window.location.href = 'admin.php?page=my-jetpack#/connection';
+ }
+
+ onUpdateWelcomeFlowExperiment( state => ( {
+ ...state,
+ variation: variationName as WelcomeFlowExperiment[ 'variation' ], // casting to 'control' or 'treatment'
+ } ) );
+ } finally {
resetNotice();
setNotice( NOTICE_SITE_CONNECTED, resetNotice );
- } );
- }, [ onActivateSite, recordEvent, resetNotice, setNotice ] );
+
+ onUpdateWelcomeFlowExperiment( state => ( { ...state, isLoading: false } ) );
+ }
+ }, [ onActivateSite, onUpdateWelcomeFlowExperiment, recordEvent, resetNotice, setNotice ] );
return (
<>
diff --git a/projects/packages/my-jetpack/_inc/components/welcome-flow/index.tsx b/projects/packages/my-jetpack/_inc/components/welcome-flow/index.tsx
index 23f683f3e3d08..94719828bcb2e 100644
--- a/projects/packages/my-jetpack/_inc/components/welcome-flow/index.tsx
+++ b/projects/packages/my-jetpack/_inc/components/welcome-flow/index.tsx
@@ -15,6 +15,11 @@ import EvaluationStep, { EvaluationAreas } from './EvaluationStep';
import styles from './style.module.scss';
import type { FC, PropsWithChildren } from 'react';
+export type WelcomeFlowExperiment = {
+ isLoading: boolean;
+ variation: 'control' | 'treatment';
+};
+
const WelcomeFlow: FC< PropsWithChildren > = ( { children } ) => {
const { recordEvent } = useAnalytics();
const { dismissWelcomeBanner } = useWelcomeBanner();
@@ -30,12 +35,16 @@ const WelcomeFlow: FC< PropsWithChildren > = ( { children } ) => {
} );
const [ isProcessingEvaluation, setIsProcessingEvaluation ] = useState( false );
const [ prevStep, setPrevStep ] = useState( '' );
+ const [ welcomeFlowExperiment, setWelcomeFlowExperiment ] = useState< WelcomeFlowExperiment >( {
+ isLoading: false,
+ variation: 'control',
+ } );
const currentStep = useMemo( () => {
- if ( ! siteIsRegistered ) {
+ if ( ! siteIsRegistered || welcomeFlowExperiment.isLoading ) {
return 'connection';
} else if ( ! isProcessingEvaluation ) {
- if ( ! isJetpackUserNew() ) {
+ if ( ! isJetpackUserNew() || welcomeFlowExperiment.variation !== 'treatment' ) {
// If the user is not new, we don't show the evaluation step
return null;
}
@@ -43,7 +52,7 @@ const WelcomeFlow: FC< PropsWithChildren > = ( { children } ) => {
}
return 'evaluation-processing';
- }, [ isProcessingEvaluation, siteIsRegistered ] );
+ }, [ isProcessingEvaluation, siteIsRegistered, welcomeFlowExperiment ] );
useEffect( () => {
if ( prevStep !== currentStep ) {
@@ -113,7 +122,8 @@ const WelcomeFlow: FC< PropsWithChildren > = ( { children } ) => {
{ 'connection' === currentStep && (
) }
{ 'evaluation' === currentStep && (
diff --git a/projects/packages/my-jetpack/_inc/context/value-store/valueStoreContext.tsx b/projects/packages/my-jetpack/_inc/context/value-store/valueStoreContext.tsx
index d73d95f18f3c9..d8902c9f2b7dc 100644
--- a/projects/packages/my-jetpack/_inc/context/value-store/valueStoreContext.tsx
+++ b/projects/packages/my-jetpack/_inc/context/value-store/valueStoreContext.tsx
@@ -3,6 +3,7 @@ import type { Dispatch, SetStateAction } from 'react';
type ValueStoreType = {
isWelcomeBannerVisible: boolean;
+ isLoadingWelcomeFlowExperiment?: boolean;
recommendedModules: JetpackModule[] | null;
recommendedModulesVisible: boolean;
};
diff --git a/projects/packages/my-jetpack/_inc/utils/side-load-tracks.ts b/projects/packages/my-jetpack/_inc/utils/side-load-tracks.ts
new file mode 100644
index 0000000000000..244f3d42a6564
--- /dev/null
+++ b/projects/packages/my-jetpack/_inc/utils/side-load-tracks.ts
@@ -0,0 +1,58 @@
+declare global {
+ interface Window {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ _tkq: Array< Array< any > >;
+ }
+}
+
+/**
+ * Function to get the current year and week number.
+ *
+ * @returns {string} The current year and week number.
+ */
+function getCurrentYearAndWeek() {
+ const date = new Date();
+ const year = date.getFullYear();
+
+ const firstDayOfYear = new Date( year, 0, 1 );
+ const daysSinceFirstDay = Math.floor(
+ ( date.getTime() - firstDayOfYear.getTime() ) / ( 24 * 60 * 60 * 1000 )
+ );
+
+ // Calculate the current week number (assuming week starts on Sunday)
+ const weekNumber = Math.ceil( ( daysSinceFirstDay + firstDayOfYear.getDay() + 1 ) / 7 );
+ const formattedWeekNumber = weekNumber.toString().padStart( 2, '0' );
+
+ return `${ year }${ formattedWeekNumber }`;
+}
+
+/**
+ * Function to dynamically load a script into the document.
+ * It creates a new script element, sets its source to the provided URL,
+ * and appends it to the document's head.
+ *
+ * @param {string} src - The URL of the script to load.
+ * @returns {Promise} A promise that resolves once the script has loaded.
+ */
+function loadScript( src: string ): Promise< void > {
+ return new Promise( resolve => {
+ const script = document.createElement( 'script' );
+ script.src = src;
+ script.onload = () => resolve();
+ document.head.appendChild( script );
+ } );
+}
+
+/**
+ * Function to sideload Tracks script.
+ *
+ * It initializes the _tkq array on the window object if it doesn't exist,
+ * and then loads the tracking script from the specified URL. Once the script has loaded,
+ * the provided callback function is called.
+ *
+ * @returns {Promise} A promise that resolves once the Tracks has been side loaded.
+ */
+export default function sideloadTracks(): Promise< void > {
+ window._tkq = window._tkq || [];
+ return loadScript( `//stats.wp.com/w.js?${ getCurrentYearAndWeek() }` );
+}
diff --git a/projects/packages/my-jetpack/changelog/add-ab-experiment-welcome-flow b/projects/packages/my-jetpack/changelog/add-ab-experiment-welcome-flow
new file mode 100644
index 0000000000000..9a9bdcf5fba96
--- /dev/null
+++ b/projects/packages/my-jetpack/changelog/add-ab-experiment-welcome-flow
@@ -0,0 +1,5 @@
+Significance: patch
+Type: changed
+Comment: Added a simple A/B experimento to the Welcome Flow on My Jetpack.
+
+