Subscribe on changes!

SSR+Suspense: the fallback slot is not hidden after hydration

avatar
Nov 19th 2022

Vue version

3.2.45

Link to minimal reproduction

https://github.com/Alexis2004/vue-ssr-suspense-fallback-issue or https://sfc.vuejs.org/#__DEV____SSR__eNqVU01vm0AQ/SvT7QEs2WClzcUlVqr00lulVj1x2cDYpYFZtLvYtSz+e2eXj4CTuooPFsO8eTPz5nEWn+s6OjQoNiKxWNWltLhNCSDJi4N/APhyIlkVGWRlgWRBUXmCgywb3EBirFa0357PkHeony4BbZvEfcqTxQPbhDb53pgaySDYokLV2LtUrFPRZzk/zAPvc9zJprRjipMPiqybJn7Gx7MFLih2siwfZfY05XiepfsNnKWSeUH7KIom4HGFV3sl8bDNbOEZjkOT6aJ2exRVrbQFlg13BeGD4pi49xI07qCFnVYVBHyYYMQO03WpKO5jdz0GpYR/PKzX6pI4PLu5+ER8tYCPHixdnA1pswEPGEXw6db/G7RNHS4GQKbIMP303Hdu6jAgpgoWnzoYV/3o7hpy7d12KIdZaeSNxASBfwj64nYJt+u1o+pizSNoep3Cz8glvrRNqV043XulxVJ08q0qWUe/jSJ2uqdJ+4RJxbh7KlhMF6fil7W12cRxQ/XTPmKd4nvOxboh59ZVrqr7D9FN9PGWL23s9H2Eplo9anU0qLljKvoBPXnMLw+oVxopR436arML7KzhRe5F00EMFmBilGuf+degcrd10Hf/9zCUkvb8xTr9rvh5ZmV/zjfYtB+8s6o0J8ouvSiPsrBAeIRv3KUwGIYajSoPOLfcCzP2qLBh+dwA+WIJN+vOct5N//JebzMeyUNGo6Uk2r8aML9O

Steps to reproduce

Open the prepared sfc.vuejs.org link

or

Clone prepared github-repo, run yarn install && yarn dev and open http://localhost:3000 URL in the browser

What is expected?

Application root component will be rendered on the server to:

Dynamic client only value: value
I'm content!

and will not change after client hydration.

What is actually happening?

Application root component rendering on the server to:

Dynamic client only value: value
I'm content!

and then replaced on client during hydration with:

Dynamic client only value: value
I'm content!
Content loading...

As you can see Suspense's fallback slot content for some reason it still shows up.

System Info

System:
    OS: macOS 13.0.1
    CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
    Memory: 1.19 GB / 32.00 GB
    Shell: 5.9 - /usr/local/bin/zsh
  Binaries:
    Node: 16.17.1 - /usr/local/opt/node@16/bin/node
    Yarn: 1.22.17 - /usr/local/bin/yarn
    npm: 8.15.0 - /usr/local/opt/node@16/bin/npm
  Browsers:
    Chrome: 107.0.5304.110
    Firefox: 106.0.5
    Safari: 16.1

Any additional comments?

  1. Client only rendering (if not html markup provided from SSR) works as expected. SSR rendering also works as expected. The only appears during client hydration.

  2. An important condition for reproducing the bug is the presence of a dynamicValue reactive variable that changes the root component template (located outside the Suspension tag).

In my project, the variable affects the name of the class that I add to the container depending on the width of the current window, but for the example, I replaced this with displaying the value of the variable in the template, and I change the variable itself inside setTimeout.

If you comment out line dynamicValue.value = 'value'; then the hydration starts working as expected.

avatar
Nov 23rd 2022
avatar
Nov 23rd 2022

@liulinboyi There seems to be a problem with the SSR in the online playground, warning node mismatch.

avatar
Nov 28th 2022

@edison1105, as I see it, the mismatch issue is only reproducible in the playground environment. In the playground there is a mismatch warning both before and after the fix. If you reproduce and issue on the local machine then there is no mismatch on the current stable version of VueJS.

avatar
Feb 28th 2023

As I understand that suspense in SSR should solve the following problems:

  • Fetch everything before showing anything
  • Load everything before hydrating anything
  • Hydrate everything before interacting with anything Using the above example suspense doesn't solve the problem that data is fetched for the entire application on the server, every thing is blocked till data is fetched.