Skip to content

fix(experiment-tag): keep anti-flicker overlay up during redirect navigation#337

Open
tyiuhc wants to merge 1 commit into
mainfrom
web/redirect-flag
Open

fix(experiment-tag): keep anti-flicker overlay up during redirect navigation#337
tyiuhc wants to merge 1 commit into
mainfrom
web/redirect-flag

Conversation

@tyiuhc

@tyiuhc tyiuhc commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes a redirect "flash" in cross-subdomain redirect experiments.

#238 (cross-subdomain redirect impression tracking) made the redirect path async: applyVariants / handleRedirect became async and handleRedirect now awaits setMarketingCookie, which resolves the registrable domain. location.replace() only queues navigation — JS keeps running and the browser keeps painting the source page until the destination commits. The anti-flicker teardown (removeAntiFlickerCss) ran inside that window and stripped the overlay (including a customer's #amp-exp-css snippet), flashing the original page mid-redirect.

The previously released version was not affected because its redirect path was synchronous (fire-and-forget cookie write, no await before location.replace()), so there was no gap for the overlay to be torn down. The flash is specific to the async redirect path introduced in #238.

Changes

Gate every anti-flicker teardown path on a new isRedirecting flag:

  • experiment.ts — set isRedirecting = true before location.replace(); skip removeAntiFlickerCss() and further remote processing in start() while a redirect is in-flight.
  • index.ts — the bootstrap .finally() and the preview/extension path skip removeAntiFlickerCss() when client.isRedirecting. The preview path returns the startClient promise so teardown flows through the single isRedirecting-gated finally.

Test plan

  • experiment.test.ts green (36 tests); asserts isRedirecting is set on the redirect path so the bootstrap skips teardown.
  • eslint + prettier clean (0 errors).
  • Manual: trigger a cross-subdomain redirect experiment and confirm no flash of the source page during navigation (normal + preview/extension paths).

Notes

…igation

Cross-subdomain redirect impression tracking made the redirect path async
(handleRedirect awaits setMarketingCookie, which resolves the registrable
domain). location.replace() queues navigation but JS keeps running and the
browser keeps painting the source page until the destination commits. The
anti-flicker teardown (removeAntiFlickerCss) then ran inside that window and
stripped the overlay — including a customer's #amp-exp-css snippet — flashing
the source page mid-redirect.

Gate every anti-flicker teardown path on a new isRedirecting flag:
- experiment.ts: set isRedirecting before location.replace(); skip
  removeAntiFlickerCss() and further remote processing in start() while a
  redirect is in-flight. Replaces an earlier never-resolving-promise stall.
- index.ts: the bootstrap .finally() and the preview/extension path now skip
  removeAntiFlickerCss() when client.isRedirecting (preview path returns the
  startClient promise so teardown flows through the single gated finally).

Isolated from the cross-subdomain redirect feature branch. Refs Questrade.

Co-authored-by: Cursor <cursoragent@cursor.com>
@tyiuhc tyiuhc requested a review from a team June 18, 2026 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant