Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

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

Aberta
#625 1 comentário 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
4/5
Tempo estimado
3-5 dias
Facilidade para iniciantes
50/100
Tipo de issue
Bug
Clareza
Razoavelmente clara
Status de atividade
Ativa
Stack de tecnologia
playwright, typescript, vite
Domínio
frontend, testing-qa

Direção de pesquisa

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.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

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.
Linguagem predominante
TypeScript
Estrelas
1.3k
Forks
180
Merge médio
1d 2h
PRs com merge (30d)
26

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de solidjs/solid-router

Todas as issues de solidjs/solid-router

Issues semelhantes

Mais issues de TypeScript

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.