Add Gandalf sign-in gate: daily-view triggered mandatory popup, hosting and Ophan identity - #16708
Conversation
Support the Gandalf sign-in gate journey (the Guardian-managed, Auxia-free 100% rollout): a dedicated persistent pageview counter, kept per country because campaigns differ by country group and idempotent per Ophan pageview id, that only advances once SDC confirms an active, eligible pageview via the gandalfSignInGate response marker; the counter is sent to /auxia/get-treatments so SDC can decide between the free-view marker and the non-dismissible popup treatment. Gandalf responses report to Ophan under a stable GandalfSignInGate identity with a per-country variant (gandalf-<country>) and never call Auxia for treatment interactions. Sign-in gate mount points are added to fronts, tag pages, galleries, pictures, liveblogs and full page interactives, and withSignInGateSlot now guarantees a host for bodies with fewer than two elements so the v2 popup can be selected everywhere the journey applies.
|
Hello 👋! When you're ready to run Chromatic, please apply the You will need to reapply the label each time you want to run Chromatic. |
🚀 Image pushed to AWS ECRImage digest: 🐛 Run the image locallyThe following can be used to run the image locally: # Refer to image using the immutable digest. Find alternatives below.
IMAGE_IDENTIFIER="@sha256:d66fd84eb88c029a8d5ba10d748d2d398a938039d5d394d988803a79e2f0751b"
# Refer to image using branch tag
# IMAGE_IDENTIFIER=":branch-nz-non-auxia-sign-in-gate"
# Refer to image using build tag
# IMAGE_IDENTIFIER=":build-31296"
# Set environment variables for the AWS CLI
AWS_PROFILE="<A_PROFILE_FROM_JANUS>"
AWS_DEFAULT_REGION="eu-west-1"
IMAGE_ACCOUNT_ID=$(aws ssm get-parameter --name /organisation/accounts/artifacts --query "Parameter.Value" --output text)
REGISTRY="${IMAGE_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"
IMAGE="${REGISTRY}/guardian/dotcom-rendering${IMAGE_IDENTIFIER}"
# Login to AWS ECR https://docs.aws.amazon.com/AmazonECR/latest/userguide/registry_auth.html
aws ecr get-login-password | docker login --username AWS --password-stdin $REGISTRY
# Pull the image
docker pull $IMAGE
# Run the image. You'll likely need to set additional flags. See https://docs.docker.com/reference/cli/docker/container/run.
docker run $IMAGE |
Support the Gandalf sign-in gate journey (the Guardian-managed, Auxia-free 100% rollout): a dedicated persistent pageview counter, kept per country because campaigns differ by country group and idempotent per Ophan pageview id, that only advances once SDC confirms an active, eligible pageview via the gandalfSignInGate response marker; the counter is sent to /auxia/get-treatments so SDC can decide between the free-view marker and the non-dismissible popup treatment. Gandalf responses report to Ophan under a stable GandalfSignInGate identity with a per-country variant (gandalf-<country>) and never call Auxia for treatment interactions. Sign-in gate mount points are added to fronts, tag pages, galleries, pictures, liveblogs and full page interactives, and withSignInGateSlot now guarantees a host for bodies with fewer than two elements so the v2 popup can be selected everywhere the journey applies.
…m-rendering into nz-non-auxia-sign-in-gate
The v2 gate only rendered once the inline #sign-in-gate host element intersected the viewport (useIsInView). That is correct for the inline dismissible gate, but the non-dismissible popup is a modal: on long pages the host sits far below the fold, so the popup never appeared. Render it on mount and record its VIEW event immediately.
…king The mandatory popup now records its VIEW event exactly once per treatment identity (treatmentId + treatmentTrackingId) by tracking the last recorded view in a ref. Visibility changes, equivalent treatment objects supplied as new props, and StrictMode effect replays no longer duplicate the view count, Ophan event, or Auxia interaction. A new treatment identity or component remount still records a fresh view as intended.
The Gandalf sign-in gate counter is now global rather than per-country. Storage keys, function signatures, and tests updated to remove countryCode parameter. Counter still advances once per eligible pageview via idempotent pageview ID tracking.
… gate The Gandalf sign-in gate now uses gu.history.dailyArticleCount instead of a dedicated persistent counter. The daily count resets each day and is sent 0-based (current pageview excluded) to SDC. Remove gandalf.ts module, incrementGandalfPageViewCount calls, ophanPageViewId parameter from canShowSignInGatePortal, and update tests and comments to reflect the new counting mechanism.
…m-rendering into nz-non-auxia-sign-in-gate
| showDefaultGate: ShowGateValues; // [3] | ||
| gateDisplayCount: number; | ||
| hideSupportMessagingTimestamp: number | undefined; // [4] | ||
| gandalfPageViewCount?: number; // [5] gandalfPageViewCount |
There was a problem hiding this comment.
is this now the same as dailyArticleCount?
There was a problem hiding this comment.
yes, the SignInGatePortal.tsx sends today's daily view count (gu.history.dailyArticleCount, 0-based) as gandalfPageViewCount
There was a problem hiding this comment.
so can it be removed, and the backend uses the existing dailyArticleCount?
There was a problem hiding this comment.
removed, it simplified a lot, thanks!
gandalfPageViewCount duplicated dailyArticleCount (same gu.history.dailyArticleCount source, sent 0-based instead of 1-based). SDC now applies the Gandalf free-allowance rule to the existing dailyArticleCount field the client already sends.
Non-article surfaces outside NZ are filtered out early to avoid unnecessary SDC requests, since Gandalf gates only appear on articles (except in NZ where fronts are also eligible).
| // allocation behind it. | ||
| const isGandalf = | ||
| auxiaGateDisplayData?.auxiaData.gandalfSignInGate === true; | ||
| const gandalfCountryCode = auxiaGateDisplayData?.gandalfCountryCode; |
There was a problem hiding this comment.
I don't think gandalfCountryCode is necessary now?
| threshold: 0, | ||
| }); | ||
|
|
||
| // The non-dismissible popup is a modal, so it must appear immediately |
There was a problem hiding this comment.
on articles it should still require scroll
…m-rendering into nz-non-auxia-sign-in-gate
…ups until visible - Add privacy, complaints-and-corrections, and the-whole-picture to denied paths - Remove gandalfCountryCode from AuxiaGateDisplayData and use fixed 'gandalf-nz' variant - Defer mandatory popup display until visibility for Article content type - Pass contentType through SignInGateSelector chain to enable content-specific logic
- Replace signInGatePlaceholder state with direct DOM query - Move scroll detection to getHasScroll function and call once on mount - Fix abTest tracking to use prop instead of building from treatmentId - Update test to verify abTest object in VIEW tracking call - Simplify setShowGate prop type to function signature
Summary
Adds the client-side half of the Gandalf sign-in gate journey: a Guardian-managed,
100% rollout sign-in gate for configured countries (decisioning stays in SDC via
gandalfSignInGateCountries, initially NZ), with no Auxia involvement.gu.history.dailyArticleCount) issent to SDC in the existing
gandalfPageViewCountfield; SDC returns themandatory popup from the 4th view of the day. The dedicated Gandalf counter
was dropped in favour of the existing daily count.
inline
#sign-in-gatehost to scroll into view (it sits below the fold onlong pages, which previously suppressed the popup entirely). Dismissible
inline gates keep the scroll-deferred behaviour.
(VIEWED/CLICKED/DISMISSED) is suppressed; responses carry the
gandalfSignInGatemarker. Non-Gandalf countries keep existing behaviour.#sign-in-gateportal hosts for fronts, tag pages, galleries,liveblogs, pictures and full-page interactives (surfaces without
ArticleRenderer), plus a short/empty-body fallback inwithSignInGateSlot.GandalfSignInGate, variantgandalf-nz.the only exclusion applied — counting uses the daily view count as-is.
Known coverage note
gu.history.dailyArticleCountonly increments for article, liveblog, gallery,video, interactive and audio pages. Fronts, tag pages and crosswords are
display-eligible but never counted — readers who only browse those never see
the gate; readers with 3 counted views will hit the modal on a front.