How to display images from structured text block in Vue/Nuxt.js (edited title)

I’m using structured text for a blog like site with Nuxt. I’m having trouble getting images that are abart of the body of a structured text field to render. I’ve been referencing this example.

I’m able to render text blocks, and can see the data that is in the image. But when I try to use an image it doesn’t convert the datocms image tag into rendered html. So this is what I see on the front end.

I’m unfamiliar with the hyperscript function in vue, and I’m a little frustrated that I can’t find any great documentation for images within the structured text field.

Please help!

Here is the vue file for a single article…

<script setup>
import { h } from "vue";
import { StructuredText as DatocmsStructuredText } from "vue-datocms";
import { Image as DatocmsImage } from "vue-datocms";
const route = useRoute()
const slug = route.params.slug;

const { data, error } = await useGraphqlQuery({
  query: `{
 article(
    filter: {slug: {eq: "${slug}"}}
  ) {
    title
    tags {
      name
    }
    body {
      blocks {
        ... on ImageRecord {
          __typename
          image {
            responsiveImage {
        webpSrcSet
        sizes
        src
        width
        aspectRatio
        alt
        title
        base64
            }
            title
            id
          }
          id
        }
      }
      value
    }
  }
  }`
});
// });
// extract the articles from the data returned by DatoCMS
const article = data.value?.article || [];

const renderBlock = ({ record }) => {
  if (record.__typename === 'ImageRecord') {
    return h(
      'div',
      { class: "image-wrapper" },
      [
        h('datocms-image', { props: { data: record.image.responsiveImage } }), //not working!
      ]
    );
  }

  return h(
    'div',
    {},
    [
      h('p', {}, "Don't know how to render a block!"),
      h('pre', {}, JSON.stringify(record, null, 2)),
    ]
  );
}

</script>

<template>
  <div class="project-content">
    {{article.title}}
    <datocms-structured-text :data="article.body" :renderBlock="renderBlock" />
      <!-- {{article.body}} -->
  </div>
</template>

<style lang="scss">
</style>

Hi @awdriggs, welcome to the forum and sorry about that!

This actually looks like a mistake/bug in our example code, whoops!

For the line that says:

h('datocms-image', { props: { data: record.image.responsiveImage } }), //not working!

Could you instead please try:

h(DatocmsImage, {  data: record.image.responsiveImage }),

(That passes the DatocmsImage component as a component instead of a string, and moves the data object one level up (without the props). Please let me know if that helps at all?

I’ll also report this to the devs to fix in our demo project. Sorry again!

Thanks Roger!
That did the trick! Glad I wasn’t doing anything wrong and could help find a mistake in the demo!

Adam

1 Like

Great! We’ve fixed it in our demo project now too.

Thanks again for the report :slight_smile:

That got me too. I forgot to have you guys update it.

GitHub Copilot
The issue could be due to several reasons. Here are a few things to check:

Check if record.image.responsiveImage is defined and has the correct structure: The datocms-image component expects the data prop to be an object with a specific structure. Make sure record.image.responsiveImage is defined and has the correct structure.

Check if datocms-image component is registered: Make sure the datocms-image component is registered in your Vue instance. If it's a global component, it should be registered with Vue.component('datocms-image', DatoCmsImageComponent). If it's a local component, it should be in the components option of your Vue instance.

Check if h function is available: The h function is used to create elements in Vue's render function. Make sure the h function is available in the scope where you're using it.

Check Vue version: If you're using Vue 3, the props object is not needed. You can pass the props directly as the second argument to h. Like this: h('datocms-image', { data: record.image.responsiveImage }).

If none of these solve the issue, please provide more context or error messages for further assistance.

@dthreatt, just to be clear, you managed to fix it, right? Or did you still need help with yours?

No I used CoPilot to figure it out. :slight_smile:

1 Like