Skip to content

fix(mobile): prevent horizontal page scroll on /stats and /mcp#6902

Merged
MarkusNeusinger merged 2 commits into
mainfrom
claude/fix-mobile-scroll-bug-kCRoC
May 16, 2026
Merged

fix(mobile): prevent horizontal page scroll on /stats and /mcp#6902
MarkusNeusinger merged 2 commits into
mainfrom
claude/fix-mobile-scroll-bug-kCRoC

Conversation

@MarkusNeusinger
Copy link
Copy Markdown
Owner

Summary

On mobile, /stats and /mcp could be side-scrolled horizontally even though no visible content extended past the viewport. Worse, that scroll position persisted across SPA navigation, so returning to / arrived horizontally offset and the left edge of the landing page was clipped.

Root cause

  • McpPage.tsx renders MUI <Table>s with inline-code spans containing un-breakable URLs like https://api.anyplot.ai/mcp/ and npx @modelcontextprotocol/inspector https://api.anyplot.ai/mcp/. Default table-layout: auto + un-breakable mono-font content forces the table to ~530px wide — well past a mobile viewport.
  • There was no global overflow-x guard, so wide content on any page leaks into viewport-level horizontal scroll.
  • RootLayout reset vertical scroll on route change but not horizontal scroll, so the offset from one page persisted into the next.

Fix

  • app/src/pages/McpPage.tsx — add overflowWrap: 'anywhere' to inlineCodeSx so URLs/commands break inside TableCells instead of forcing the table wider than the viewport.
  • app/src/styles/tokens.css — add overflow-x: clip on html, body as a defense-in-depth safety net. clip (not hidden) keeps the sticky masthead working since it doesn't create a scroll container.
  • app/src/components/RootLayout.tsx — also reset window.scrollX on pathname change so any leftover offset doesn't carry into the next page.

Test plan

  • yarn type-check passes
  • yarn lint passes (no new warnings)
  • yarn test --run passes for McpPage, StatsPage, RootLayout
  • Manually verify on a mobile viewport (≤ 375px) that /mcp and /stats no longer side-scroll
  • Manually verify that navigating from /mcp/ no longer arrives horizontally offset
  • Verify the sticky masthead still sticks while scrolling on /about, /legal, /

Generated by Claude Code

Long URLs in MCP page tables (e.g. `npx @modelcontextprotocol/inspector ...`)
have no break opportunities, forcing the auto-layout table wider than a
mobile viewport. The viewport scroll then persisted across SPA navigation,
so returning to / arrived with the page horizontally offset and the left
edge clipped.

- inlineCodeSx: add `overflowWrap: anywhere` so URLs/commands wrap inside
  TableCells instead of pushing the table past viewport width.
- tokens.css: add `overflow-x: clip` on html/body as a safety net for any
  other wide element. `clip` (not `hidden`) keeps the sticky masthead
  working since it doesn't create a scroll container.
- RootLayout: also reset window.scrollX on route change so a leftover
  offset from one page doesn't carry into the next.
Copilot AI review requested due to automatic review settings May 16, 2026 10:26
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a mobile bug where /stats and /mcp could be scrolled horizontally, with the offset persisting across SPA navigation and clipping the landing page.

Changes:

  • Add overflowWrap: 'anywhere' to inline-code style in McpPage so long URLs/commands wrap inside TableCells.
  • Add overflow-x: clip on html, body as a defense-in-depth guard (preserves sticky positioning).
  • Reset window.scrollX on route changes in RootLayout so leftover horizontal offset doesn't carry between pages.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
app/src/pages/McpPage.tsx Allow inline-code content to break, preventing tables from forcing horizontal overflow on mobile.
app/src/styles/tokens.css Global overflow-x: clip on html, body as a viewport-level safety net.
app/src/components/RootLayout.tsx Reset horizontal scroll position on pathname change.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@MarkusNeusinger MarkusNeusinger enabled auto-merge (squash) May 16, 2026 11:50
@MarkusNeusinger MarkusNeusinger merged commit b27dfe0 into main May 16, 2026
7 checks passed
@MarkusNeusinger MarkusNeusinger deleted the claude/fix-mobile-scroll-bug-kCRoC branch May 16, 2026 11:51
MarkusNeusinger added a commit that referenced this pull request May 18, 2026
Version bump for the v2.4.0 release. Release notes will be attached to
the tag once this lands.

## Highlights since v2.3.0

- **R / ggplot2 added as the 10th library** + multi-language pipeline
(#6944, #6961, #7052). 30 ggplot2 implementations landed across
foundational plot types.
- **In-app feedback widget** (#7143).
- **Stats page** with Plausible visitors chart + daily-impl timeline
(#6608).
- **Language across the site**: `/plots?lang=` filtering, cross-language
carousel, language in URLs and titles (#7141, #7142, #7144).
- **UI polish**: pseudo-function styling for 404 / footer / empty state
/ library card (#6436); mobile fixes for `/stats`, `/mcp`, breadcrumb +
FAB (#6902, #7283).
- **Pipeline**: review-retry listener + stuck-jobs watchdog (#6084);
daily-regen 2h → hourly (#6943).
- **Dependencies**: mypy 1.20→2.1, urllib3 2.6→2.7, authlib bump,
react/mui/python-minor groups.
- ~1200 implementation regenerations across all 10 libraries.

No SemVer-breaking changes.

**Full Changelog:**
v2.3.0...main

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

3 participants