Skip to content

fix(search): Stop mobile Kapa modal scroll trap#18325

Merged
sergical merged 12 commits into
masterfrom
sergical/fix/mobile-kapa-modal-scroll-lock
Jun 10, 2026
Merged

fix(search): Stop mobile Kapa modal scroll trap#18325
sergical merged 12 commits into
masterfrom
sergical/fix/mobile-kapa-modal-scroll-lock

Conversation

@sergical

@sergical sergical commented Jun 9, 2026

Copy link
Copy Markdown
Member

DESCRIBE YOUR PR

Fixes the mobile Kapa AI modal scroll trap: when opened from the in-search "Ask Sentry about…" suggestion, scroll was trapped on the document instead of the modal content.

Root cause: the in-search AI button opened Kapa without closing the mobile search overlay, so our overlay's body scroll lock and Kapa's own lock were both active. On iOS, two competing body locks trap scroll on the document. (Opening Kapa from the standalone "Ask AI" button worked precisely because it has no overlay/lock.)

  • Close the mobile search overlay before opening Kapa (deferred one frame) so Kapa owns the body scroll lock exclusively
  • Consolidate the ad-hoc document.body.style.overflow locks (mobile search + sidebar) into a shared, reference-counted useBodyScrollLock hook that restores the prior overflow value — so overlays no longer clobber each other's (or Kapa's) lock

IS YOUR CHANGE URGENT?

Help us prioritize incoming PRs by letting us know when the change needs to go live.

  • Urgent deadline (GA date, etc.):
  • Other deadline:
  • None: Not urgent, can wait up to 1 week+

SLA

  • Teamwork makes the dream work, so please add a reviewer to your PRs.
  • Please give the docs team up to 1 week to review your PR unless you've added an urgent due date to it.
    Thanks in advance for your help!

PRE-MERGE CHECKLIST

Make sure you've checked the following before merging your changes:

  • Checked Vercel preview for correctness, including links
  • PR was reviewed and approved by any necessary SMEs (subject matter experts)
  • PR was reviewed and approved by a member of the Sentry docs team

🤖 Generated with Claude Code

Opening the Kapa AI modal from the in-search suggestion left the mobile
search overlay (and its body scroll lock) mounted underneath, so our lock
and Kapa's own lock fought and Kapa's content couldn't scroll on mobile.

Close the overlay before opening Kapa so Kapa owns the body scroll lock
exclusively, and consolidate the ad-hoc body-overflow locks into a shared
reference-counted useBodyScrollLock hook so overlays no longer clobber each
other's (or Kapa's) lock.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
develop-docs Ready Ready Preview, Comment Jun 9, 2026 11:41pm
sentry-docs Ready Ready Preview, Comment Jun 9, 2026 11:41pm

Request Review

Comment thread src/hooks/useBodyScrollLock.tsx
…red value

A captured previous value could be a third party's transient overflow:hidden
(e.g. Kapa). Re-applying it on release would leave the page unscrollable.
Clearing the inline style fails gracefully and is correct for this app, where
body overflow is only ever a transient scroll lock.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread src/components/header.tsx Outdated
The onAskAi handler only closed the search overlay, so if the sidebar was
also open its body scroll lock survived into the Kapa modal and recreated the
iOS scroll trap. Release every overlay's lock before Kapa opens via a shared
closeSidebar helper (also dedupes the existing search-button logic).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread src/components/search/index.tsx Outdated
The lock was released in a passive effect, whose ordering vs the
requestAnimationFrame that opens Kapa is not guaranteed. If Kapa opened first,
our later cleanup cleared body overflow and wiped Kapa's lock, re-trapping
scroll on mobile. Release in a layout effect so it runs synchronously on commit,
before the rAF. Also trims verbose comments.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The home-page hamburger overlay rendered fixed inset-0 but never locked body
scroll, so the page scrolled behind it on mobile. Apply useBodyScrollLock for
homeMobileNavOpen, mirroring the search/sidebar overlays, and close it on
navigation and on resize to desktop so the lock can't be stranded.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
On subpages the mobile sidebar stacked all 11 top-level sections above the
current section's page nav, pushing the scrollable nav far below the fold. Wrap
the section list in a single collapsed 'Menu' disclosure so the page nav sits at
the top; the active section is conveyed by the page nav heading, and tapping
Menu reveals all sections.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
sergical and others added 2 commits June 9, 2026 13:56
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…roll

The home hamburger overlay had no internal scrolling, so on short screens its
lower items were unreachable once body scroll was locked. Add overflow-y-auto +
overscroll-contain to the overlay. Also lock overflow on the documentElement (the
actual scroll container), not just body — body-only overflow doesn't stop
overscroll/rubber-band chaining to the page at the scroll bounds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
sergical and others added 2 commits June 9, 2026 14:08
Locking overflow stops normal scroll but not iOS overscroll/rubber-band, which
drags the page behind a fixed overlay and visually detaches it from the header
at the scroll bounds. Set overscroll-behavior:none on the documentElement in the
scroll lock, and on the home nav overlay itself.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
With the section menu expanded on short screens, the fixed overflow:hidden
sidebar and its inner scroll region fought over the height, so the page nav
below the menu was unreachable. On mobile, scroll the whole sidebar and let the
inner nav regions grow naturally so the menu and page nav scroll together.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b8af7db. Configure here.

Comment thread src/components/sidebar/style.module.scss Outdated
The mobile .toc override sat in an earlier block with equal specificity to the
later base .sidebar .toc rule, so the base flex:1/overflow:auto won on cascade
and platform/develop sidebars kept a nested inner scroll. Move the mobile
overrides into the base .toc and .sidebar-main blocks so they apply at <768px.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Use overscroll-behavior: contain on the open mobile sidebar so it keeps
the natural overscroll/bounce at its bounds while still preventing scroll
chaining to the page behind. `none` killed the bounce (felt locked).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@sfanahata sfanahata left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looking much better! Thanks @sergical 🚀

@sergical sergical merged commit 7c18269 into master Jun 10, 2026
23 checks passed
@sergical sergical deleted the sergical/fix/mobile-kapa-modal-scroll-lock branch June 10, 2026 17:00
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.

2 participants