diff --git a/static/app/views/onboarding/components/scmPlatformFeaturesCore.tsx b/static/app/views/onboarding/components/scmPlatformFeaturesCore.tsx
index 0111a6b70854..8ae8d913076a 100644
--- a/static/app/views/onboarding/components/scmPlatformFeaturesCore.tsx
+++ b/static/app/views/onboarding/components/scmPlatformFeaturesCore.tsx
@@ -167,11 +167,12 @@ export function ScmPlatformFeaturesCore({
const currentPlatformName = getPlatformName(currentPlatformKey);
- // Fire scm_platform_selected once per repo when detection auto-resolves a
- // platform and the user hasn't explicitly chosen one. Otherwise a user who
- // accepts the recommendation and clicks Continue never emits the event,
- // leaving the funnel without a platform-selected step. The ref is re-armed
- // on repo change above so a switch to a new repo fires the event again.
+ // Adopt the first detected platform once per repo when the user hasn't
+ // explicitly chosen one: commit it to the host so flows without a Continue
+ // boundary (single-view project creation) get a platform without an explicit
+ // pick, and fire scm_platform_selected so a user who just accepts the
+ // recommendation still emits a platform-selected funnel step. The ref is
+ // re-armed on repo change above so a switch to a new repo adopts again.
useEffect(() => {
if (
autoDetectionTrackedRef.current ||
@@ -181,12 +182,19 @@ export function ScmPlatformFeaturesCore({
return;
}
autoDetectionTrackedRef.current = true;
+ setPlatform(detectedPlatformKey);
trackAnalytics(PLATFORM_SELECTED_EVENT[analyticsFlow], {
organization,
platform: detectedPlatformKey,
source: 'detected',
});
- }, [detectedPlatformKey, selectedPlatform?.key, organization, analyticsFlow]);
+ }, [
+ detectedPlatformKey,
+ selectedPlatform?.key,
+ organization,
+ analyticsFlow,
+ setPlatform,
+ ]);
// Wizard-driven platforms render an informational variant since the wizard CLI
// owns product configuration and toggles aren't actionable.
diff --git a/static/app/views/onboarding/scmPlatformFeatures.spec.tsx b/static/app/views/onboarding/scmPlatformFeatures.spec.tsx
index 5e70cab868a0..ed3278915b73 100644
--- a/static/app/views/onboarding/scmPlatformFeatures.spec.tsx
+++ b/static/app/views/onboarding/scmPlatformFeatures.spec.tsx
@@ -120,7 +120,7 @@ describe('ScmPlatformFeatures', () => {
expect(within(radioGroup).getByText('Django')).toBeInTheDocument();
});
- it('auto-selects first detected platform', async () => {
+ it('auto-selects and commits first detected platform', async () => {
MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/repos/42/platforms/`,
body: {
@@ -135,14 +135,15 @@ describe('ScmPlatformFeatures', () => {
},
});
- render(
- ,
- {organization}
- );
+ const props = defaultProps({selectedRepository: mockRepository});
+ render(, {organization});
expect(
await screen.findByRole('heading', {level: 3, name: 'Available with Next.js'})
).toBeInTheDocument();
+ expect(props.onPlatformChange).toHaveBeenCalledWith(
+ expect.objectContaining({key: 'javascript-nextjs'})
+ );
});
describe('feature card variants', () => {