Skip to content

Improve AdSense CTA dismissal UX #11302

@nfmohit

Description

@nfmohit

Feature Description

As @benbowler raised here, the layout shift caused when the AdSense setup CTA is dismissed can lead to a confusing user experience.

Here is a screencast of the current experience:
https://github.com/user-attachments/assets/74b144b7-4089-4c97-8a6f-6adb5d475e64

The AdSense section is removed when the user clicks the "Maybe later" button, and the PageSpeed widget comes into view, which itself takes a considerable amount of time to run tests and return results. This loading state may make the user assume that their dismissal is still in progress, which is not the case.

A proposed solution was to instead scroll the user back to the top, which is not ideal as indicated by @techanvil here.

A nicer experience would be for the section to have a brief fade out rather than immediately disappearing, and for the PSI widget to slide up with an ease-in transition rather than just replacing it in the next frame.

This is a candidate to run by Sigal for a better UX solution.


Do not alter or remove anything below. The following sections will be managed by moderators only.

Acceptance criteria

  • When dismissing the AdSense Setup CTA widget on the SIte Kit Dashboard, the widget should use a "fade-out" transmission to disappear and the page should "scroll" up to the heading of the PageSpeed Insights widget.

Implementation Brief

  • Add a reusable dismissal-transition wrapper for widgets: assets/js/googlesitekit/widgets/components/DismissibleWidget.js.
    • Props: isVisible, isDismissing, isDismissed, children, optional onDismissComplete.
    • Internal phase state: visible / dismissing / hidden.
    • Use one shared transition constant (e.g. DISMISS_TRANSITION_MS).
    • Behavior:
      • When eligible and not dismissing/dismissed: phase = visible.
      • When dismiss starts: phase = dismissing and keep rendering content.
      • After DISMISS_TRANSITION_MS:
        • if dismissed persisted (isDismissed === true): phase = hidden, invoke onDismissComplete.
        • if dismiss failed (isDismissed !== true): phase returns to visible.
    • Expose phase via wrapper class (e.g. googlesitekit-widget--dismissing) for CSS animation.
  • Add generic smooth-scroll helper for post-dismiss repositioning (dashboard-level, not module-specific), using existing scroll utilities:
    • In a shared util (e.g. assets/js/util/scroll.js companion), implement logic to scroll to the next visible widget-area heading relative to the dismissed widget container.
    • Compute target offset with getNavigationalScrollTop.
    • Perform global.scrollTo( { top, behavior: 'smooth' } ).
    • Safe no-op if target cannot be resolved or top is invalid.
  • Update assets/js/modules/adsense/components/dashboard/AdSenseConnectCTAWidget.js to use DismissibleWidget:
    • Keep existing dismissItem, tooltip, and tracking flow intact.
    • Replace current immediate WidgetNull gating tied to isDismissingItem === false.
    • Feed lifecycle props into DismissibleWidget:
      • isVisible: current eligibility condition.
      • isDismissing: CORE_USER.isDismissingItem( ADSENSE_CTA_WIDGET_DISMISSED_ITEM_KEY ).
      • isDismissed: CORE_USER.isItemDismissed( ADSENSE_CTA_WIDGET_DISMISSED_ITEM_KEY ).
    • On dismiss completion callback, invoke the generic scroll helper.
    • Remove any hardcoded PageSpeed anchor coupling from this widget flow.
  • Add reusable styles for dismissal phase in shared widget styles:
    • Update assets/sass/widgets/_widgets.scss:
      • Add dismissing modifier/class with fade-out transition (opacity) and disabled interaction (pointer-events: none).
    • Keep styling generic at widget layer (not AdSense-specific override).

Test Coverage

  • Add tests for assets/js/googlesitekit/widgets/components/DismissibleWidget.js:
    • visible > dismissing > hidden on success.
    • visible > dismissing > visible on failure.
    • onDismissComplete fires only on successful completion.
  • Update assets/js/modules/adsense/components/dashboard/AdSenseConnectCTAWidget.test.js:
    • "Maybe later" does not unmount widget immediately.
    • Dismissing class/phase is present during transition.
    • Widget unmounts only after transition timeout when dismiss succeeds.
    • Failed dismiss restores visible state.
    • Generic scroll helper is called on successful dismiss completion.
  • Add tests for the new generic scroll helper:
    • Scrolls to next visible widget-area heading when available.
    • No-op when no valid target exists.

QA Brief

  • On a site where AdSense is not connected and the Setup CTA has not been dismissed, open the Site Kit dashboard and scroll down to the AdSense Setup CTA.
  • Click "Maybe later" and verify the CTA fades out smoothly instead of disappearing instantly.
  • Verify the page smoothly scrolls up so the PageSpeed Insights heading sits below the sticky header once the fade completes.
  • Verify the existing "Got it" tooltip still appears once during the dismissal.
  • Reload the dashboard and verify the CTA no longer renders.

Changelog entry

  • Fix layout shift when the AdSense setup prompt is dismissed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Low priorityTeam SIssues for Squad 1Type: EnhancementImprovement of an existing feature

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions