Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loop context is lost when rendering nested slot in v-for using external component in SSR #7095

Closed
john-eos opened this issue Nov 10, 2022 · 6 comments · Fixed by #7184
Closed
Labels
❗ p4-important Priority 4: this fixes bugs that violate documented behavior, or significantly improves perf. 🐞 bug Something isn't working scope: compiler scope: ssr

Comments

@john-eos
Copy link

Vue version

3.2.44

Link to minimal reproduction

https://stackblitz.com/edit/github-iqylbs?file=src/pages/BreaksSSR.vue

Steps to reproduce

  1. Open StackBlitz example
  2. Navigate to page "Breaks SSR", see it working in CSR
  3. Reload page to force render in SSR
  4. Property "row" was accessed during render but is not defined on instance

What is expected?

SSR should behave as CSR

What is actually happening?

SSR causes app crash

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 16.14.2 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 7.17.0 - /usr/local/bin/npm
  npmPackages:
    vue: ^3.2.25 => 3.2.44

Any additional comments?

This is a weird one, it is probably easier to understand looking at the reproduction example.

When defining slot content / templates in a v-for loop, the current loop element is undefined in that slot. However, this only occurs in very specific cases:

  1. Page is rendered in SSR
  2. Slot Templates are defined in v-for
  3. Content referencing the loop element is using an external component that is also using slots

It works perfectly fine on client side or if the component used to render the content is internal (part of the same project, not pre-built from a library).

Additional context

We came across this issue when starting to extract a component library from our project prototype.

We have a dynamic table / listing component used to render a list of objects based on a column configuration. This component also provides dynamic scoped slots for every column in case we want to customize the rendering.

Under the hood, it uses our basic table components to render table rows and cells. After we moved those table components to our new component library, the dynamic listing suddenly broke in SSR.

However, I made the reproduction example as simple as I could and used a random UI library instead of our own code to make sure the same error happens.

@baiwusanyu-c
Copy link
Member

baiwusanyu-c commented Nov 14, 2022

I'm not sure if it's a vue problem, but in the reproduction you provided I noticed that you used vant's Badge component, and everything seems to work fine after removing it. Could it be a problem with the component library? In nuxt environment you can use the <client-only> component to temporarily circumvent it

<client-only>
   <Badge :content="5">
      <slot name="slot0" />
   </Badge>
</client-only>

@john-eos
Copy link
Author

Hi, vant's Badge is just a random example. We encountered this issue with our own components after moving them to our component library package.

The error seems to occur with any external component that uses a slot.

@john-eos
Copy link
Author

@baiwusanyu-c I've created a quick reproduction that uses a insanely simple component (<div><slot /></div>) pre-built with vite to rule out any issues with vant:

https://stackblitz.com/edit/github-iqylbs-cayzpv?file=src/CompiledComponent.js

Same error, only in SSR.

@zhangzhonghe
Copy link
Member

zhangzhonghe commented Nov 20, 2022

Seems like a compiler bug, both locations in the figure below should be compiled to row.name.

屏幕截图 2022-11-20 174306

See here.

@XjulI1
Copy link

XjulI1 commented Aug 29, 2023

Any idea when this will be fixed ? We currently migrate to Nuxt 3 and it's a blocking issue for us in SSR.

@Tahul
Copy link

Tahul commented Sep 27, 2023

Hey @zhangzhonghe ; in your reproduction there is missing code/content.

If I implement the nested-slots component, and simple data in the example, I get it running with no hydration mismatches.

Here is a link.

I've encountered a similar bug in a similar dynamic row/cells content setup in Nuxt contexts, but fail to reproduce in SFC playground.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
❗ p4-important Priority 4: this fixes bugs that violate documented behavior, or significantly improves perf. 🐞 bug Something isn't working scope: compiler scope: ssr
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants