@@ -8,7 +8,7 @@ import React, {
88} from 'react' ;
99import type { QueryObserverResult } from '@tanstack/react-query' ;
1010import { useRouter } from 'next/router' ;
11- import { useFeatureValue } from '@growthbook/growthbook-react' ;
11+ import { GrowthBookContext } from '@growthbook/growthbook-react' ;
1212import type { AnonymousUser , LoggedUser } from '../lib/user' ;
1313import { deleteAccount , logout as dispatchLogout } from '../lib/user' ;
1414import type { AccessToken , Boot , Visit } from '../lib/boot' ;
@@ -24,6 +24,7 @@ import {
2424 onboardingUrl ,
2525 webFunnelPrefix ,
2626} from '../lib/constants' ;
27+ import { featureInlineLogin } from '../lib/featureInlineLogin' ;
2728
2829export interface LoginState {
2930 trigger : AuthTriggersType ;
@@ -79,6 +80,7 @@ export interface AuthContextData {
7980 isGdprCovered ?: boolean ;
8081 isValidRegion ?: boolean ;
8182 isFunnel ?: boolean ;
83+ inlineLoginEnabled ?: boolean ;
8284}
8385
8486const isExtension = checkIsExtension ( ) ;
@@ -159,20 +161,35 @@ export const AuthContextProvider = ({
159161 isAndroidApp,
160162} : AuthContextProviderProps ) : ReactElement => {
161163 const [ loginState , setLoginState ] = useState < LoginState | null > ( null ) ;
164+ const [ inlineLoginEnabled , setInlineLoginEnabled ] = useState < boolean > ( ) ;
165+ const inlineLoginEnabledRef = useRef < boolean > ( ) ;
162166 const endUser = user && 'providers' in user ? user : null ;
163167 const referral = user ?. referralId || user ?. referrer ;
164168 const referralOrigin = user ?. referralOrigin ;
165169 const router = useRouter ( ) ;
166170 const isFunnelRef = useRef ( ! ! router ?. pathname ?. startsWith ( webFunnelPrefix ) ) ;
171+ const growthbookContext = useContext ( GrowthBookContext ) ;
172+ const growthbook = growthbookContext ?. growthbook ;
167173 const isValidRegion = useMemo (
168174 ( ) => ! invalidPlusRegions . includes ( geo ?. region ) ,
169175 [ geo ?. region ] ,
170176 ) ;
171- // Inline-login experiment flag. Source of truth for the local default lives
172- // in `lib/featureManagement.ts` as `featureInlineLogin`. We can't import it
173- // here because `featureManagement` → `graphql/posts` → `AuthContext` would
174- // be a cycle, so the default is duplicated below; keep them in sync.
175- const isInlineLoginEnabled = useFeatureValue < boolean > ( 'inline_login' , true ) ;
177+ const evaluateInlineLogin = useCallback ( ( ) : boolean => {
178+ if ( ! isNullOrUndefined ( inlineLoginEnabledRef . current ) ) {
179+ return inlineLoginEnabledRef . current ;
180+ }
181+
182+ const isEnabled =
183+ growthbook ?. getFeatureValue (
184+ featureInlineLogin . id ,
185+ featureInlineLogin . defaultValue ,
186+ ) === true ;
187+
188+ inlineLoginEnabledRef . current = isEnabled ;
189+ setInlineLoginEnabled ( isEnabled ) ;
190+
191+ return isEnabled ;
192+ } , [ growthbook ] ) ;
176193
177194 return (
178195 < AuthContext . Provider
@@ -186,6 +203,7 @@ export const AuthContextProvider = ({
186203 firstVisit : user ?. firstVisit ,
187204 trackingId : user ?. id ,
188205 shouldShowLogin : loginState !== null ,
206+ inlineLoginEnabled,
189207 showLogin : useCallback (
190208 ( { trigger, options = { } } ) => {
191209 const hasCompanion = ! ! isCompanionActivated ( ) ;
@@ -196,6 +214,7 @@ export const AuthContextProvider = ({
196214 }
197215
198216 const params = new URLSearchParams ( globalThis ?. location . search ) ;
217+ const shouldUseInlineLogin = ! isExtension && evaluateInlineLogin ( ) ;
199218
200219 setLoginState ( { ...options , trigger } ) ;
201220 if ( isExtension ) {
@@ -206,19 +225,20 @@ export const AuthContextProvider = ({
206225 params . set ( AFTER_AUTH_PARAM , window . location . pathname ) ;
207226 }
208227
228+ const onboardingPath = isExtension
229+ ? `${ onboardingUrl } ?${ params . toString ( ) } `
230+ : `/onboarding?${ params . toString ( ) } ` ;
231+
209232 // Inline login experiment: render the modal in-place instead of
210233 // redirecting to /onboarding. Extension keeps the redirect because
211234 // it has no host page to mount the modal on.
212- if ( isInlineLoginEnabled && ! isExtension ) {
235+ if ( shouldUseInlineLogin ) {
213236 return ;
214237 }
215238
216- const onboardingPath = `${ onboardingUrl } ?${ params . toString ( ) } ` ;
217- router . push (
218- isExtension ? onboardingPath : `/onboarding?${ params . toString ( ) } ` ,
219- ) ;
239+ router . push ( onboardingPath ) ;
220240 } ,
221- [ router , isInlineLoginEnabled ] ,
241+ [ evaluateInlineLogin , router ] ,
222242 ) ,
223243 closeLogin : useCallback ( ( ) => setLoginState ( null ) , [ ] ) ,
224244 loginState,
0 commit comments