How can I get my images' alt texts from within my Vue components?

I have a Vue component that renders images. Here is a subset of that code that I use to inspect the information I have about the image:

export default {
  data ({content}) {
    console.log('content', content) // This includes information about the image
    return {
      […]
    }
  },
  […]
}

When I look through this info, however, the alt text is nowhere to be found.

I would have expected it to be in the content somewhere, like content.image.alt, or since Kirby puts things in arrays sometimes, perhaps something like content.image[0].alt.

Yet, I can’t find the alt text anywhere.

I’ve seen other posts on the forums which propose to extract the alt text by converting an image object to a file object with some toFile() function, but that all happens in PHP land. How do I do this in Vue land?

What is content? Somehow I’m missing a bit of context. Is that a custom block?

This is a custom block, yes.

And the content is what is being given to it by Kirby, based on the fields I set up for the block in its .yml file. It looks something like this:

{
  "image": [
    {
      "filename":"fireworks-celebration-light.png",
      "dragText":"(video: fireworks-celebration-light.png)",
      "icon":{
        "type":"file-image",
        "ratio":"3/2",
        "back":"pattern",
        "color":"#f0c674",
        "cover":false
      },
      "id":"home/fireworks-celebration-light.png",
      "image":{
        "ratio":"3/2",
        "back":"pattern",
        "cover":false
      },
      "info":"",
      "link":"/pages/home/files/fireworks-celebration-light.png",
      "text":"fireworks-celebration-light.png",
      "type":"video",
      "url":"http://127.0.0.1:8000/media/pages/home/23d02c80ae-1636585178/fireworks-celebration-light.png",
      "uuid":"fireworks-celebration-light.png"
    }
  ],
  "isvideo":false,
  "layout":"default",
  "imageposition":"left",
  "title": "TITLE FOR ABOVE THE IMAGE",
  "body": "DESCRIPTION ABOVE THE IMAGE",
  "buttons":[
    {
      "label":"BUTTON LABEL",
      "link":{
        "type":"page",
        "value":[
          {
            "dragText":"(link: The Experience)",
            "hasChildren":false,
            "icon":{
              "type":"page",
              "ratio":null,
              "back":"pattern",
              "color":"#c5c9c6"
            },
            "id":"the-experience",
            "image":null,
            "info":"",
            "link":"/pages/the-experience",
            "text":"The Experience",
            "url":"http://127.0.0.1:8000/en/the-experience"
          }
        ]
      },
      "size":"default",
      "type":"secondary",
      "width":"auto"
    }
  ]
}

The .yml file looks like this:

name: MY CUSTOM BLOCK
icon: file

fields:
  image:
    type: files
    max: 1
    template: image
    ratio: 1/1
    layout: cards
    size: large
  layout:
    label: Layout
    width: 2/6
    type: radio
    columns: 2
    default: auto
    options:
      default : Hor
      vertical : Ver
  imagePosition:
    when:
      layout: default
    width: 3/6
    label: Image position
    type: radio
    columns: 3
    default: auto
    options:
      auto : Auto
      left : Left
      right : Right
  separ_image:
    type: line
  title:
    type: text
  body:
    type: writer
    icon: text
    inline: true
    marks: true
      - bold
      - italic
      - underline
      - link
    nodes: false
  separ_content:
    type: line
  buttons: fields/Buttons

this.content.image[0].alt should give you access to the image’s alt field?

this.content looks like this:

{
  "image":[
    {
      "filename":"partner_trust.jpg",
      "dragText":"(image: partner_trust.jpg)",
      "icon":{
        "type":"file-image",
        "ratio":"3/2",
        "back":"pattern",
        "color":"#de935f",
        "cover":false,
        "url":"http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner_trust.jpg",
        "cards":{
          "url":"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw",
          "srcset":"http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner-trust-352x.jpg 352w, http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner-trust-864x.jpg 864w, http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner-trust-1408x.jpg 1408w"
        },
        "list":{
          "url":"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw",
          "srcset":"http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner-trust-38x38.jpg 1x, http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner-trust-76x76.jpg 2x"
        }
      },
      "id":"home/partner_trust.jpg",
      "image":{
        "ratio":"3/2",
        "back":"pattern",
        "cover":false,
        "url":"http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner_trust.jpg",
        "cards":{
          "url":"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw",
          "srcset":"http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner-trust-352x.jpg 352w, http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner-trust-864x.jpg 864w, http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner-trust-1408x.jpg 1408w"
        },
        "list":{
          "url":"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw",
          "srcset":"http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner-trust-38x38.jpg 1x, http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner-trust-76x76.jpg 2x"
        }
      },
      "info":"",
      "link":"/pages/home/files/partner_trust.jpg",
      "text":"partner_trust.jpg",
      "type":"image",
      "url":"http://127.0.0.1:8000/media/pages/home/1eb259e36f-1636585178/partner_trust.jpg",
      "uuid":"partner_trust.jpg"
    }
  ],
  "layout":"default",
  "title":"Some title for success stories",
  "body":"Some long text about success stories",
  "buttons":[
    {
      "label":"Read more about our success stories",
      "link":{
        "type":"page",
        "value":[
          {
            "dragText":"(link: success-stories text: Success Stories)",
            "hasChildren":true,
            "icon":{
              "type":"folder",
              "ratio":null,
              "back":"pattern",
              "color":"#c5c9c6"
            },
            "id":"success-stories",
            "image":null,
            "info":"",
            "link":"/pages/success-stories",
            "text":"Success Stories",
            "url":"http://127.0.0.1:8000/en/success-stories"
          }
        ]
      },
      "size":"default",
      "type":"secondary",
      "width":"auto"
    }
  ]
}

It also doesn’t contain the alt.

So this.content.image[0].alt just returns undefined

Hm, then you would need to make a call to the API

Really? Does the started kit make API calls to get the alt texts for its images?

Well, the alt text is not an inherent property of the file, it is part of the content and the content is not passed automatically. So yes, either an API call or you store the alt text in the text/info props and get it from there.

“store the alt text in the text/info props and get it from there.” Not sure what you mean, could you give me an example?

Sure!

Field in your block, use query syntax to pass the alt text to the info property.

  image:
    type: files
    info: "{{file.alt}}"

Then fetch the info in your component:

this.content.image[0].info

Admittedly a bit hackish, but the easiest way.

This looks like it’s working! Thanks. However I’m not sure I understand. I tried to use a word different than info but that didn’t work. Is info a special property? Where is this info thing documented?

Yes, as I mentioned above, info/text are props of the pages/files/users fields. You can find them documented here for example:

Ah, I see what you mean by “a little hackish”.

Thanks