Skip to content

ref(experiments): Default useExperiment reportExposure to false#114217

Merged
jaydgoss merged 6 commits intomasterfrom
jaygoss/useexperiment-default-no-exposure
Apr 30, 2026
Merged

ref(experiments): Default useExperiment reportExposure to false#114217
jaydgoss merged 6 commits intomasterfrom
jaygoss/useexperiment-default-no-exposure

Conversation

@jaydgoss
Copy link
Copy Markdown
Member

@jaydgoss jaydgoss commented Apr 28, 2026

TL;DR

Flip useExperiment's reportExposure default from true to false. Pairs with an upcoming BE change that stops the org serializer from auto-logging exposure on every page load. With BE auto-logging gone, the FE becomes the source of truth, so call sites have to be intentional about whether the user is actually being rendered one of the experiment variants.

Why a true default is wrong now

useExperiment can be consumed inside shared components whose surrounding flow can render something other than the control or active variant. When that happens the user has not seen the experiment, but a default-true call site logs them as exposed anyway. Flipping to false makes the opt-in visible at the call site, so exposure is only recorded where a variant is actually rendered.

Effect on onboarding-scm-experiment

  • onboarding.tsx:184 opts in with reportExposure: true. Single point that fires the FE exposure POST and the synchronous browser Amplitude.groupIdentify for the parent SCM experiment.
  • useWelcomeAnalyticsEffect and useWelcomeHandleComplete previously relied on the default and now fall through to false. Both run in flows where the user may not have rendered either variant.
  • onboarding.tsx:190 (onboarding-scm-project-details-experiment) keeps its reportExposure: hasScmOnboarding gate and is unchanged.

The backend org serializer auto-logs exposure for every experiment-mode
flagpole flag whenever an org is loaded, so the FE default of true was
producing redundant exposure POSTs from any call site that just wanted
to read the assignment. Flip the default to false and require call
sites to opt in at the single point that represents the user actually
seeing the experiment. The synchronous browser-side Amplitude group
property write still fires from that opt-in site to win the race
against events on the same mount.

Onboarding flips onboarding.tsx to reportExposure: true; the other
SCM onboarding consumers fall through to the new false default.
@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Apr 28, 2026
Drop the reference to the backend serializer auto-logging exposure;
that path is going away. Frame the FE as the source of truth so each
call site has to opt in intentionally.
Replace the double-counting framing with the underlying concern: shared
components that consume useExperiment can render neither the control
nor the active variant, and reporting exposure there misattributes the
user as having seen the experiment when they have not.
Drop the TestComponent default of true, which existed only to keep
existing exposure tests passing after the hook default flipped to
false. The default hid the new behavior from the test file. Each test
that exercises exposure now passes the prop explicitly so the spec
reflects how consumers must use the hook.
Drop the shared-component aside; the rule about opting in at the
variant-rendering site already covers it.
@jaydgoss jaydgoss marked this pull request as ready for review April 28, 2026 19:48
@jaydgoss jaydgoss requested review from a team as code owners April 28, 2026 19:48
Comment thread static/gsApp/hooks/useExperiment.tsx Outdated

export function useExperiment(options: UseExperimentOptions): UseExperimentResult {
const {feature, reportExposure = true} = options;
const {feature, reportExposure = false} = options;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if there was no default value: so people are forced to learn about this. I've found in previous experiences that exposure is not something people intuitively think about or add even when it's needed.

Drop the default value entirely so every call site has to opt in or out
explicitly. Pairs with the FE-as-source-of-truth shift: exposure is easy
to miss when reading code, and a required flag forces the decision at
the call site.

The two onboarding hooks that previously relied on the default
(useWelcomeAnalyticsEffect, useWelcomeHandleComplete) now pass
reportExposure: false explicitly, matching the intent already described
in the PR body.
@jaydgoss jaydgoss merged commit 37ffcc2 into master Apr 30, 2026
68 checks passed
@jaydgoss jaydgoss deleted the jaygoss/useexperiment-default-no-exposure branch April 30, 2026 17:51
cleptric pushed a commit that referenced this pull request May 5, 2026
)

## TL;DR
Flip `useExperiment`'s `reportExposure` default from `true` to `false`.
Pairs with an upcoming BE change that stops the org serializer from
auto-logging exposure on every page load. With BE auto-logging gone, the
FE becomes the source of truth, so call sites have to be intentional
about whether the user is actually being rendered one of the experiment
variants.

## Why a true default is wrong now
`useExperiment` can be consumed inside shared components whose
surrounding flow can render something other than the control or active
variant. When that happens the user has not seen the experiment, but a
default-true call site logs them as exposed anyway. Flipping to `false`
makes the opt-in visible at the call site, so exposure is only recorded
where a variant is actually rendered.

## Effect on `onboarding-scm-experiment`
- `onboarding.tsx:184` opts in with `reportExposure: true`. Single point
that fires the FE exposure POST and the synchronous browser
`Amplitude.groupIdentify` for the parent SCM experiment.
- `useWelcomeAnalyticsEffect` and `useWelcomeHandleComplete` previously
relied on the default and now fall through to `false`. Both run in flows
where the user may not have rendered either variant.
- `onboarding.tsx:190` (`onboarding-scm-project-details-experiment`)
keeps its `reportExposure: hasScmOnboarding` gate and is unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants