Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"TypeError: globalThis.astroAsset is undefined" and render broken when displaying images pulled from content collection inside hydrated Vue component #11042

Closed
1 task
cengique opened this issue May 14, 2024 · 6 comments · Fixed by #11171
Labels
needs triage Issue needs to be triaged

Comments

@cengique
Copy link

Astro Info

$ npm run astro info

> astro-content-vue@0.0.1 astro
> astro info

Astro                    v4.8.3
Node                     v21.7.3
System                   Linux (x64)
Package Manager          npm
Output                   static
Adapter                  none
Integrations             @astrojs/vue
which: no xclip in (...)

If this issue only occurs in one browser, which browser is a problem?

Firefox and Chrome

Describe the Bug

Hi,
We've been working on constructing our first Astro+AgnosticUI+Vue site: https://tapggc.org/
Code here: https://github.com/TAP-GGC/tap-ws1-astro-agnosticui

We hit an issue when displaying images from content collection in a hydrated Vue component. We get a "TypeError: globalThis.astroAsset is undefined" in the browser console and more importantly the Vue component stops rendering in the dev version. In the build version, the component draws once (correctly and including the image) and then disappears (with the same error).

This only happens when the component is hydrated. I submitted a support request on Discord and I was told this may be a bug.

I created a blank Astro project from scratch to demonstrate the issue, but I'm also pasting the files here. Thanks in advance!

content/config.js:

// 1. Import utilities from `astro:content`
import { defineCollection, z } from 'astro:content';
// 2. Define your collection(s)
const blogCollection = defineCollection({
    type: 'content', // v2.5.0 and later
    schema: ({image}) => z.object({
      title: z.string(),
      tags: z.array(z.string()),
      image: image().optional(),
    }),
  });
// 3. Export a single `collections` object to register your collection(s)
//    This key should match your collection directory name in "src/content"
export const collections = {
  'posts': blogCollection,
};

content/posts/test.md:

---
title: Hello
tags: [none]
image: './qrcode_tapggc-org.png'
---

testC.astro:

---
import VueComp from '../components/vue.vue';
---
<VueComp client:load/>

components/vue.vue:

<script setup>
import { getCollection } from 'astro:content';
const blogEntries = await getCollection('posts');
</script>

<template>
<ul>
    <li v-for="blog in blogEntries">
      <a :href="`/my-blog-url/${blog.slug}`">{{blog.data.title}}</a>
      <img :src="blog.data.image.src">
    </li>
</ul>
</template>

What's the expected result?

No error and Vue continues rendering. Image shows for a short time but then the whole component disappears.

Link to Minimal Reproducible Example

https://github.com/cengique/astro-content-vue

Participation

  • I am willing to submit a pull request for this issue.
@github-actions github-actions bot added the needs triage Issue needs to be triaged label May 14, 2024
@matthewp
Copy link
Contributor

You shouldn't use astro:content in a client component. In 5.0 we might prevent this from being possible.

@cengique
Copy link
Author

@matthewp makes sense. Then getting the content in astro file and passing to Vue component as props works:
https://github.com/cengique/astro-content-vue/tree/fix

@Trombach
Copy link

@cengique Just FYI, you can also pass an astro component to a slot in vue, which would be another way to achieve this

@cengique
Copy link
Author

Thanks @Trombach ! I think in this case we need to filter the content entries through controls in the Vue component. I assume we won't have access to do it if it's inside a pre-rendered slot?

@Trombach
Copy link

Trombach commented May 14, 2024

@cengique I'm not sure what exactly you're trying to do, but I guess you could filter entries before they get passed to the vue component. Btw, I saw that you typed your collection prop as Object. You might want to look into the CollectionEntry type helper

Edit: and you might want to do the filter outside of vue anyway because you can do it directly on the getCollection call https://docs.astro.build/en/guides/content-collections/#filtering-collection-queries

@cengique
Copy link
Author

Edit: and you might want to do the filter outside of vue anyway because you can do it directly on the getCollection call https://docs.astro.build/en/guides/content-collections/#filtering-collection-queries

Thanks @Trombach ! I'm actually trying to filter dynamically with a text input and dropdown selections, so I can't pre-filter the content. But, I finally got it to work on the original codebase!

@cengique I'm not sure what exactly you're trying to do, but I guess you could filter entries before they get passed to the vue component. Btw, I saw that you typed your collection prop as Object. You might want to look into the CollectionEntry type helper

Will check this out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs triage Issue needs to be triaged
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants