rdunk / sanity-blocks-vue-component

[DEPRECATED] Vue component for rendering block content from Sanity
MIT License
71 stars 10 forks source link

custom serializer types is error when using ssr: true #22

Closed baydiwo closed 3 years ago

baydiwo commented 3 years ago

I have created 2 custom serializer types, when develop using ssr: false, all images and video iframe shows up correctly, but when using ssr: true, there's and error in nuxt generate, when in browser, all custom types is showing at first load then disappearing. this is my nuxtJs code:

<template v-if="$fetchState.pending && !contents.length"> </template>
    <template v-else>
<article>
              <client-only>
                <PortableText
                  :blocks="contents.slugData.body"
                  :serializers="serializers"
                />
              </client-only>
            </article>
<template>

import PortableText from 'sanity-blocks-vue-component'
export default {
  name: 'NewsSlug',
  components: {
    PortableText,
    LazyHydrate,
  },
  async fetch() {
    if (this.$route.query.preview === 'true') {
      this.contents = await sanityClient.fetch(previewQuery, this.$route.params)
    }
    this.contents = await sanityClient.fetch(prodQuery, this.$route.params)
  },
  data() {
    return {
      heroImageSize: {
        width: 672,
        height: 488,
      },
      serializers: {
        marks: {
          internalLink: InternalLink,
          link: ExternalLink,
        },
        types: {
          fullWidthImage: ({ node, children }) => (
            <client-only>
              <SanityImageCaption image={node} />
            </client-only>
          ),
          videoEmbed: ({ node, children }) => (
            <client-only>
              <VideoEmbed node={node} />
            </client-only>
          ),
        },
      },
      contents: {},
      shareList: ['facebook', 'twitter', 'linkedin'],
    }
  }, 
}

sanityImageCaption components

<template>
  <figure>
    <img
      :key="image._key"
      v-lazy-load
      :src="imageUrl"
      :alt="image.alt"
      class="object-center object-cover h-full w-full"
    />

    <figcaption>{{ image.caption }}</figcaption>
  </figure>
</template>

<script>
import imageUrlBuilder from '@sanity/image-url'
import sanityClient from '~/sanityClient'
const builder = imageUrlBuilder(sanityClient)
export default {
  props: {
    image: {
      type: Object,
      required: true,
    },
    auto: {
      default: 'format',
      type: String,
    },
    fit: {
      default: 'max',
      type: String,
    },
  },
  computed: {
    imageUrl() {
      return builder.image(this.image).auto(this.auto).fit(this.fit)
    },
  },
}
</script>

error message from nuxt generate

 WARN  Cannot stringify a function renderWithStyleInjection                                                                                                                                                                                                         11:42:31

 WARN  Cannot stringify a function hook                                                                                                                                                                                                                             11:42:31

 WARN  Cannot stringify a function hook                                                                                                                                                                                                                             11:42:31

 WARN  Cannot stringify a function fullWidthImage                                                                                                                                                                                                                   11:42:31

 WARN  Cannot stringify a function videoEmbed

ERROR   /news/contact-us                                                                                                                                                                                                                                           11:42:35

TypeError: Cannot read property '_key' of undefined
    at /Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/@sanity/block-content-to-hyperscript/lib/generateKeys.js:7:15
    at Array.map (<anonymous>)
    at module.exports (/Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/@sanity/block-content-to-hyperscript/lib/generateKeys.js:6:17)
    at blocksToNodes (/Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/@sanity/block-content-to-hyperscript/lib/blocksToNodes.js:27:21)
    at blocksToNodes (/Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/@sanity/block-content-to-hyperscript/lib/internals.js:14:14)
    at blocksToVue (/Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/sanity-blocks-vue-component/lib/blocksToVue.js:51:10)
    at render (/Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/sanity-blocks-vue-component/lib/BlockContent.js:46:12)
    at /Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/vue/dist/vue.runtime.common.prod.js:6:22507
    at Ie (/Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/vue/dist/vue.runtime.common.prod.js:6:22689)
    at /Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/vue/dist/vue.runtime.common.prod.js:6:23819
    at Le (/Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/vue/dist/vue.runtime.common.prod.js:6:24170)
    at e._c (/Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/vue/dist/vue.runtime.common.prod.js:6:32380)
    at a.render (pages/news/_slug.vue?d307:1:0)
    at a.t._render (/Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/vue/dist/vue.runtime.common.prod.js:6:35273)
    at /Users/Baydiwo/Projects/dark-horse-nuxtjs/node_modules/vue-server-renderer/build.prod.js:1:70637
    at runMicrotasks (<anonymous>)

I've tried using client-only but it seems not solving the problem

rdunk commented 3 years ago

I'm a bit out of the loop with the Vue 2 version and Nuxt, but is it possible to define your type components as Vue components rather than functions? I don't recall if that ever worked or not.

I'd also suggest looking at the @nuxtjs/sanity plugin if you're sticking with Vue 2 as that is most likely more actively maintained for that version. I'll still accept PRs for versions <1.x but plan on dedicating the time I have to supporting Vue 3.

baydiwo commented 3 years ago

Hi @rdunk thanks for your reply, I've tried using @nuxtjs/sanity but the error still same,

WARN  Cannot stringify a function fullWidthImage                                                                                                                                                                                                                   

 WARN  Cannot stringify a function videoEmbed

I'm using "nuxt": "^2.15.6", the problem is only when I set ssr: true.

rdunk commented 3 years ago

Have you tried defining your type serializers as Vue components (as you've done with marks)?

baydiwo commented 3 years ago

Hi, thank you for your assist, I still stuck for few days so I move to block-content-to-html.

rdunk commented 3 years ago

No worries. If you want to discuss this further I'll reopen the ticket.