Static GitHub Issues

[1210] Client-Server Dom Matching Bug

prev: stderr: [object Promise] in production
next: Multiple components not rendered with async data as props (reopened)

I know with rc3 it says not to add issues - but I don't think this is a documentation thing, and in fact it may be more to do with vue-server-renderer but I wanted to run it past you here if that's OK.

I have a page here: pages/_pages/index/index.vue And all is OK if I do this:

<template>
  <div>
    <div v-if="hasRole('ROLE_ADMIN')">
      <component :is="editor"
                 :model="body"
                 :endpoint="patchUrl"
                 name="body"
      />
    </div>
    <div>
      <text-block :content="body" :patchUrl="patchUrl" name="body" />
    </div>
  </div>
</template>

and

created () {
      // https://vuejs.org/v2/guide/components.html#Advanced-Async-Components
      this.editor = () => ({
        component: import('~/components/Cms/Quill')
      })
    }

And my text block component is

<template>
  <div>
    <div v-if="!hasRole('ROLE_ADMIN')"
         :class="textClass"
         v-html="staticContent"
    ></div>
  </div>
</template>

I move the dynamic component inside my text block component and the server-side and client-side DOM error appears.

Here are the full files when the error happens: pages/_page/index/index.vue

<template>
  <div>
    <div>
      <text-block :content="body" :patchUrl="patchUrl" name="body" />
    </div>
  </div>
</template>

<script>
  import { mapMutations, mapGetters } from 'vuex'
  import TextBlock from '~/components/Template/TextBlock.vue'
  import ApiForm from '~/components/Form/ApiForm.vue'
  import _FormId from '~/components/Form/_FormId'
  import MetaDescription from '~/components/Template/MetaDescription'

  export default {
    mixins: [_FormId],
    props: ['body', 'form', 'hasForm', 'patchUrl', 'metaDescription'],
    components: {
      TextBlock,
      ApiForm,
      MetaDescription
    },
    computed: {
      ...mapGetters({
        hasRole: 'hasRole'
      })
    },
    methods: {
      ...mapMutations({
        setFormValid: 'forms/setFormValid'
      }),
      getFormResponse (res) {
        return this.setFormValid({
          formId: this.formId,
          valid: res.data.valid,
          errors: res.data.form.vars.errors,
          models: res.data.form.children
        })
      }
    }
  }
</script>

<style lang="sass">
  .form-columns
    margin-top: .5rem
</style>

components/template/TextBlock.vue

<template>
  <div>
    <div v-if="!hasRole('ROLE_ADMIN')"
         :class="textClass"
         v-html="staticContent"
    ></div>
    <div v-else>
      <component :is="editor"
                 :model="content"
                 :endpoint="patchUrl"
                 :name="name"
      />
    </div>
  </div>
</template>

<script>
  import { mapGetters } from 'vuex'

  export default {
    data () {
      return {
        staticContent: null,
        editor: null
      }
    },
    props: {
      content: {
        type: String,
        required: true
      },
      name: {
        type: String,
        required: true
      },
      patchUrl: {
        type: String,
        required: false,
        default: ''
      }
    },
    computed: {
      ...mapGetters({
        hasRole: 'hasRole'
      }),
      textClass () {
        return [
          'content',
          this.$route.name
        ]
      }
    },
    methods: {
      updateContent (newContent) {
        this.staticContent = newContent
      }
    },
    created () {
      // https://vuejs.org/v2/guide/components.html#Advanced-Async-Components
      this.editor = () => ({
        component: import('~/components/Cms/Quill')
      })
      this.staticContent = this.content
    }
  }
</script>

I've checked the vars are all there passing through, both times the dynamic component is added on the created method - Is this a Nuxt issue do you think or vue-server-renderer?

The error: [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.

Thanks very much in advance.

<!--cmty--><!--cmty_prevent_hook--><div align="right"><sub><em>This question is available on <a href="https://nuxtjs.cmty.io">Nuxt.js</a> community (<a href="https://nuxtjs.cmty.io/nuxt/nuxt.js/issues/c1067">#c1067</a>)</em></sub></div>