core icon indicating copy to clipboard operation
core copied to clipboard

Suspense unmounts with an error if it renders a component with a root node implementing a client-only behavior

Open ksenkso opened this issue 10 months ago • 2 comments

Vue version

3.5.13

Link to minimal reproduction

https://play.vuejs.org/#eNqFU8tu2zAQ/BWWF9uoa6FoT65sNC1yaIG2QV3kxIsqrWQmNCnwoTgQ9O/dFSXZRRLHJ3J3Zji7Grf8qq5XTQC+5qnLraw9c+BDvRVaHmpjPWtZAaXUcOUedf7VYFGD9ktmoWQdK605sBkKzD4JLXRutPOMUGzzLG8+X7DNlkXt+WyVUIcMzBaLMwW3N0EVu715+J+Oqvju3NsABE+T6Bnd4sXDoVaZB7wxlv4N3hvNPudK5vcbwS9IvnmpJ/jWm6pSkCZRLkrvgqtBO2DNO1lekEY64ZFBpXik38FVyLqVHthbdhtA8NhLonwy6uM1Taap+JJ7h+spZbW6c0bjJ2sJL3iO6lKB/VV7iesTfM36DvUypczD975GW1uO9XwP+f0z9Tt3pJrgNxYc2AbNTT2f2QpwKmpf737CEc9T82CKoBB9ofkbnFGBPEbYl6ALtH2G691+68MhdfXHXR89LmIciowSsuvxgmNsaLEvjX6y+2H1secJ3eEWx8hdyrzRP0zQHoqnQaesxWjfWFO7ef8eftI123mLrtFctzhFWbpBachumSnXh1fo6ZHhX9ErTfhVk6kAyKKxEd+9lvhCNmMiJ5FTBPfvt21LPlnXpQneSKHvEC9XmXNIzDN74uBYg0oEJogcIjqd4qOAMw0kbfxIY4+4/jP4WZjpcd79A7O0hXo=

Steps to reproduce

  1. Click the toggle button

What is expected?

The Suspense component unmounts without an error.

What is actually happening?

The Suspense component unmounts, but the app crashes - the error pops up and the toggle button no longer works.

System Info


Any additional comments?

I was trying to implement a loader for async components with some reload logic (retries, reload when connection is restored - things like that). And one of the components had a client-only logic in it: it was rendering the actual content only after the mounted hook. I didn't use the errorComponent/onError from the AsyncComponentOptions because i needed to reload the component again, so i used Suspense and its fallback slot.

I understand that Suspense is experimental and i have been able to resolve this issue in my project by wrapping the template of the async component in a static div, but the issue itself is there.

ksenkso avatar Feb 20 '25 11:02 ksenkso

a workaround

  <Suspense v-if="shouldShowAsyncComponent">
+    <div>
      <Comp msg="Vite + Vue" />
+    </div>
  </Suspense>

see playground

edison1105 avatar Feb 20 '25 12:02 edison1105

FYI - it's very easy to hit this problem with inertia. Put a <Suspense> in your layout, and your app will crash with Unhandled error during execution of component update and Failed to execute 'insertBefore' on 'Node'. Only when visiting non-async inertia pages.

Just add the magic <div> wrapper as a workaround. Thanks all, we love vue

gurgeous avatar May 22 '25 05:05 gurgeous