withastro / astro

The web framework for content-driven websites. ⭐️ Star to support our work!
https://astro.build
Other
46.26k stars 2.44k forks source link

Not able to render <Image/> component from astro:assets when src is taken from frontmatter #6880

Closed pexeixv closed 1 year ago

pexeixv commented 1 year ago

What version of astro are you using?

2.3.0

Are you using an SSR adapter? If so, which one?

No

What package manager are you using?

pnpm

What operating system are you using?

Windows

What browser are you using?

Brave

Describe the Bug

Trying to setup a blog website and following the following folder structure:

.
└── src/
    ├── assets/
    │   ├── post-1.jpg
    │   ├── post-2.jpg
    │   └── post-3.png
    ├── content/
    │   └── blog/
    │       ├── post-1.md
    │       ├── post-2.md
    │       └── post-3.md
    ├── layouts/
    │   └── BlogPostLayout.astro
    └── pages/
        └── blog/
            ├── index.astro
            └── [slug].astro

post-1.md looks like this

---
layout: ../../layouts/BlogPostLayout.astro
title: A Post about Important Items Of Life
date: 2022-11-20
author: Darnell McClure
description: Have you ever wondered what the most important items of life are? Well, wonder no more!
draft: false
tag: Reference Docs
priority: 10
titleImage: ../assets/post-1.jpg
---

Nisi duis ex aliqua eu officia eiusmod duis magna pariatur. Irure laborum qui aliqua nulla esse cillum laborum aliquip nulla elit. Id id Lorem duis irure cillum culpa. Nulla sint et aliqua velit do. Nulla sit sit proident consectetur enim ullamco aliqua in reprehenderit ullamco officia.

[slug].astro looks like this:

---
import { Image } from "astro:assets";
import { getCollection } from "astro:content";
import BlogPostLayout from "../../layouts/BlogPostLayout.astro";
export async function getStaticPaths() {
  const blogPosts = await getCollection(
    "blog",
    ({ data }) => !data.draft && data.date < new Date()
  );
  return blogPosts.map((post) => ({
    params: { slug: post.slug },
    props: { post },
  }));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<BlogPostLayout title={post.data.title}>
  <h1>{post.data.title}</h1>
  <span>{post.data.titleImage}</span>
  <Image src={post.data.titleImage} alt="" height={250} width={800} format="webp" />
  <Content />
</BlogPostLayout>

However, a broken image rendered with src localhost:3000/assets/post-1.jpg.

Please help me out.

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-36ea95?file=src/layouts/BlogPostLayout.astro

Participation

Princesseuh commented 1 year ago

You're passing a string to Image, not an image reference. Strings references are intended for remote images and as such, are passed as-is.

To use images in the frontmatter, you should use Content Collections's image() schema.

See https://docs.astro.build/en/guides/assets/#update-content-collections-schemas for more information.

pexeixv commented 1 year ago

Hey @Princesseuh! Thanks for the prompt reply. I'm still not able to get it to work. How should I be declaring the image in frontmatter of markdown files?

---
titleImage: image('../assets/post-1.jpg')
---

Or something like this in the layout file?

---
import { Image, getImage } from "astro:assets";
import BlogLayout from "./BlogLayout.astro";
const {title,titleImage} = Astro.props.frontmatter
---
<BlogLayout {title}>
    BlogPostLayout
    <Image src={getImage(titleImage)} height={100} width={400} format="webp" alt={title}/>
    <slot/>
</BlogLayout>

Both of these don't work and I just can't figure it out.

ricardo-rp commented 8 months ago

@pexeixv Did you manage to find a solution? I'm having the same issue.

Joshuajrodrigues commented 5 months ago

Seems like this no longer works ? @Princesseuh Ive tried refering to the following docs https://docs.astro.build/en/guides/images/#images-in-content-collections

However this seems outdated as src throws type error when i pass cover to it. Also cover has src, format, width and height properties available now which gives a type error.