2

I have a problem with Vue SSR. In my project I have a page called slug, where depending on the data received in asyncData, the appropriate component is mounted. It looks more or less like this:

<div>
  <component-a v-if='type === a' />
  <component-b v-else-if='type === b' />
  <component-c v-else-if='type === c' />
</div>

<script>
export default {
  asyncData({ store }) {
    store.dispatch('product/fetchAsync') 
  },
  computed () {
   type () {
     return this.$store.state.type
    }
  }
}
</script>

However, Vue is not able to perform SSR hydration. Is there a possibility that this is due to v-if statement? How to solve this correctly? The only thing I can think of is prefixes and making each component a separate page, without v-if. But the client would like to avoid this.

kissu
  • 40,416
  • 14
  • 65
  • 133
FeransoeOE
  • 21
  • 1
  • 3
  • you could do `` and ditch the if/else's – Lawrence Cherone Nov 04 '21 at 14:42
  • also btw it would be `v-if="type === 'a'"`, your not wrapping a,b,c as strings – Lawrence Cherone Nov 04 '21 at 14:44
  • I'm pretty sure that the snippet that you've shared does not have any issue with hydration. Can you be sure of where this is coming from? – kissu Nov 04 '21 at 16:00
  • This is most likely because you are fetching the data only on the client-side and then are changing the HTML structure based on the data. This causes the Dom structure to differ on the server-side vs. the client-side. Server-side: no component is rendered because the type is undefined. Client-side: a component is rendered. This mismatch causes the SSR hydration to quit. Solution make the fetch call in the server as well or wrap your components with client-only (assuming you are using Nuxt). – Roskow Nov 04 '21 at 16:24
  • Yep, basically this question and the answers there should greatly help you: https://stackoverflow.com/q/47862591/8816585 – kissu Nov 04 '21 at 18:51

1 Answers1

2

As some comments say, your html structure at server side (where ssr is happening) don't know if the conditions for rendering an item or other are true.

You can use v-show instead of v-if. The difference is that v-show will render that element but with no data. This way your html won't change and hydration is successful

javier Cuervas
  • 823
  • 10
  • 11