Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

2.0: <A> click before hydration settles renders root <Loading> fallback mid-hydration and leaves the page unresponsive

オープン
#625 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
50/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
playwright, typescript, vite

調査の方向性

Start with the App.tsx root Loading boundary and the deferred data patterns in routes/index.tsx and routes/insureds.tsx. Reproduce an immediate Playwright click before the root onSettled flag, then trace the router navigation and hydration behavior. Done means the early click no longer produces hydration-key-miss warnings, duplicate DOM, or an unresponsive page.

索引モデルが issue の本文から書いたものです。

説明

Describe the bug

With SSR and a root <Loading> boundary, a click on an <A> link that lands before hydration has settled is taken by the router, which starts a client-side navigation. The next route's data is not ready yet, so the root <Loading> fallback is rendered while the page is still hydrating. Hydration then fails to claim the server's DOM, and the page stops responding: the server-rendered content stays on screen, but no further clicks do anything.

Console output when it happens:

Hydration key miss for "170110": no server-rendered element carries this key (template: <main>Loading…). A detached element was created instead; its subtree will not appear in the document or become interactive.
Hydration completed with 8 unclaimed server-rendered node(s): <main ...>

In the DOM, the page is drawn twice: the unclaimed server-rendered <main> and a second client-rendered copy.

Your Example Website or App

No public repro, sorry: it is a private app. The relevant shape is small, though:

// App.tsx
export default function App() {
  return (
    <Router>
      {(props) => (
        <Loading fallback={<main>Loading…</main>}>
          {props.children}
        </Loading>
      )}
    </Router>
  );
}

// routes/index.tsx: data read with deferStream
const landing = createMemo(() => getLanding(), { deferStream: true }); // getLanding = query(..., "landing")
// ...renders <A href="/insureds">Insureds</A>

// routes/insureds.tsx: its own query + deferStream, same pattern
Steps to Reproduce the Bug or Issue
  1. Server-render a page like the above (SSR, streaming, dev server).
  2. As soon as the server's content is visible, before hydration has settled, click an <A> link to another route whose data is not cached.
  3. The target route's data is fetched, the root <Loading> fallback renders mid-hydration, and the hydration-key-miss warnings above appear.
  4. The page no longer responds to clicks.

Driving this with Playwright (sign in, then click the link immediately when the heading is visible, with no wait), about 1 in 4 runs fail. If the test first waits for a flag set in onSettled at the root, it passes 40 out of 40.

Expected behavior

A click that arrives before hydration settles should not break hydration. For example, the router could ignore or queue it until hydration settles, or fall back to a normal full-page navigation.

Screenshots or Videos

No response

Platform
  • OS: Linux (Arch, kernel 7.2)
  • Browser: Chromium, via Playwright 1.63 (headless)
  • Version: @solidjs/router 2.0.0-next.26, solid-js / @solidjs/web 2.0.0-rc.9, @solidjs/vite-plugin 3.0.0-next.44, Vite 8.3, Node 26
Additional context
  • I could not check the latest (@solidjs/router 2.0.0-next.30 + solid-js 2.0.0-rc.10): after upgrading, the app failed to load a route module (Failed to fetch dynamically imported module .../src/routes/index.tsx?pick=default&pick=$css), unrelated to this bug, so I could not run the repro there.
  • Possibly related, but a different trigger: solidjs/solid#3610 (hydrate starting before the records script).
  • Workaround we use in tests: set an attribute on <html> from onSettled in a component inside the root <Loading>, and wait for it before interacting after each full page load.
主要言語
TypeScript
スター
1.3k
フォーク
180
平均マージ
1日 2時間
マージ済み PR(30日)
26

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

solidjs/solid-router のほかの issue

solidjs/solid-router の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。