v-if breaks nuxt ssr

Viewed 4371

If I use fetched data (fetchPolicy: 'cache-and-network') from apollo in v-if, it will throw vue.runtime.esm.js:619 [Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.

<template>
  <div
    <div v-if="test">
      {{ test }}
    </div>
  </div>
</template>

but if I use it just as variable to render it works fine.

<template>
  <div>
    {{ test }}
  </div>
</template>

The data in real usage is object, that I need to conditionaly render and pass to another components with v-if.

I have tried geting the data trough get, doing watch over the data and seting them manually, but eventually everything broke.

regarding comment: if I console the test data it will go -> true on server -> false on client and then true on the client again, if I remove the test from v-if it goes: true on server and true on client

this has nothing to do with structure, in real project it has bunch of components and it works just fine if the data isnt used in condition

5 Answers

For anyone facing the same problem, I have fixed it by setting cache-and-network after the mount and all works just fine.

mounted() {
  this.$apollo.queries.getCampaign.setOptions({
    fetchPolicy: 'cache-and-network',
  })
}

You are trying to make the root element of a component conditionnally disappear, which creates an inconsistency in the virtual DOM.

Can you try:

<template>
  <div>
    <template v-if="test">
      {{ test }}
    </template>
  </div>
</template>

SSR is sometimes difficult to debug and such problems occure quite often.

https://ssr.vuejs.org/#why-ssr

some external libraries may need special treatment to be able to run in a server-rendered app.

This may be the point. Some vue-components cannot be run via SSR out of the box. This is why I asked about the content from the server.

So the easiest fix could be to wrap your component with the <no-ssr> tag. You can do this for each component separatly to find out which one causes the problem. Once you have isolated the component you can keep the <no-ssr> tag on it and migrate it's functions to the mounted area of your client component.

from my experience, nuxt will failed in SSR if you are using v-if unless you wrap in <no-ssr> or <client-only>

If it is a small component you can also use v-show instead.

Related