Skip to content

Every page logs 21 React hydration errors at load, and sitemap.xml emits localhost:3000 URLs #76

Description

@mmcky

Found on 2026-09-10 while verifying the v2.6.1 theme bump (#75) on the deployed site. Neither problem is caused by that release: the hydration errors fire at page load and not on any navigation, and the same theme version deployed elsewhere is clean. Two findings, both about how this site is built and deployed rather than about the theme; they may split into two issues if the causes turn out to be unrelated.

1. Every page logs React #418 ×21 and #423 ×1 at load

Measured in headless Chromium against https://quantecon.github.io/lecture-wasm/ with a pageerror listener, four seconds after load.

Page #418 #423 code cells outline h2s
/ (landing) 21 1 0 0
/inflation-history/ 21 1 18 3
/french-rev/ 21 1 22 7
/long-run-growth/ 23 1 25 5

React #418 is "hydration failed because the initial UI does not match what was rendered on the server"; #423 is the client-render fallback after that. The count is essentially constant and is 21 on a landing page with no code cells, so the mismatch is in the page chrome, not the lecture content. Errors are zero during an outline click and zero on Back, so they are unrelated to the QuantEcon/quantecon-theme.mystmd#186 fix carried by v2.6.1.

What has been ruled out. The lecture-python-programming build of the same theme version (https://6aa28a51be58fa42c169aa3c--epic-agnesi-957267.netlify.app/, deployed at the site root on Netlify) logs zero errors on the same probe, with the same live-compute slot and launch control present. On this site, server-rendered href/src attributes match the hydrated DOM exactly (the only additions after hydration are the two thebe-*.min.js scripts the client injects), so the mismatch is not in link targets. Neither site uses the git-metadata plugin, so it is not a relative-time string.

Leading candidate. This site is the only known deploy of the theme under a subpath: ci.yml builds with BASE_URL: /lecture-wasm for GitHub Pages, while the theme's own fixture and the lecture-python-programming preview both serve from /. A base-URL-dependent piece of chrome that the server renders one way and the client another would produce a small, constant per-page count like this. The contents drawer here has 41 entries against the Netlify site's 26, if the count matters. Reproducing locally is myst build --html with BASE_URL=/lecture-wasm served under that prefix, then comparing the SSR text of the header and drawer against the hydrated DOM; the theme's FOUC guard notes describe the same #418/#423 pair being deliberately provoked in a control test, which is a useful reference for what a mismatch looks like.

Cost today: React discards the server markup and re-renders on the client, which is the "styled → unstyled → styled" flicker the theme's critical-CSS work exists to cover, plus wasted work on every page load. If the cause is in the theme rather than the site config, it goes to QuantEcon/quantecon-theme.mystmd with this measurement attached.

2. sitemap.xml emits http://localhost:3000 for every URL

https://quantecon.github.io/lecture-wasm/sitemap.xml contains 43 localhost:3000 entries: the stylesheet reference and every <loc>. Search engines get a sitemap that points nowhere. The page config's domain field also reads http://localhost:3000, but that appears on the Netlify site too and is myst's static-build default, so the sitemap is the consumer-visible symptom. The fix is presumably declaring the site's public URL in myst.yml (site.domains) so the sitemap resolves against it; worth checking whether that same setting is what the hydration mismatch above depends on, since both are "where does this site think it lives" questions.

Probe scripts were run from the theme repo's checkout with its Playwright install; the measurement is reproducible with a plain page.on('pageerror') count after load.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions