#Using a posts frontmatter image

31 messages · Page 1 of 1 (latest)

light smelt
#
// pages/posts.astro
const allPosts = await Astro.glob("../pages/posts/*.md");

---
allPosts.map((post)) => (
<img
                      src={post.frontmatter.image.url}
                      alt={post.frontmatter.image.alt}
                      class="rounded-3xl p-2"
                    />
# pages/posts/Capsule.md
---
image:
  url "../../images/capsule.gif"
---
# pages/posts/Banana.md
---
image:
  url "imagehost.com/banana"
---

Im trying to use the image defined in the markdown post's frontmatter on my blog index page. Following the guide online, I defined it and used it the way shown. But when Im trying to use local images, it does not work.

So Banana.md's image shows up, but Capsule.md's does not.

I kinda wanted to use <Image/> anyways since I want the benefits and I learnt that way first anyways, but from looking around it doesn't seem possible?

So I guess my question is, whats the proper way to do this?

Thanks

hexed citrus
#

It's currently not (exactly) possible for images in Markdown files outside of content collections

light smelt
#

ah, so i should move away from doing
/src/pages/posts/blargh.md
in favour of src/content ?

#

😨 seems scary compared to the ease of just having files exist

#

ill give it a crack , looking at the docs for schema creation now

hexed citrus
#

It is definitely a bit involved! We hope to add the feature directly to Markdown files eventually, though it is a bit complicated (we essentially cannot really tell that an arbitrary string is supposed to be an image)

light smelt
#

typescript schemas gave me issues but i finally did it

#

perhaps a callout to content collections should be in the build a blog tutorial

#

i wouldve just did it this way in the first place if i knew

hexed citrus
light smelt
#

I used that doc to help me migrate to content collections it was very helpful

light smelt
#

I have one thing left that I can't figure out, which is local images using <Image/> on the generated posts for my content collection blog.

#

I understand that you have to import an image before you can use it with <Image/>

#
#divider.astro (just to illustrate working <Image/>
---

const { Class } = Astro.props;
import { Image } from "astro:assets";
import sadKirblet from "../images/svg/sad-kirblet.svg"
---

<div class={`${Class} divider pb-5`}>
  <Image src={sadKirblet} alt="Kirblet!" class="w-16" />
</div>
#

like that. but what if if I can't import it?

in my case, i have a card component for the index of my blog

#
#projects.astro
{
          allProjects.map((projects) => (
            <>
              <Card
                url={projects.slug}
                image={projects.data.image}
                imageUrl={projects.data.image?.url}
                alt={projects.data.image?.alt}
                description={projects.data.description}
                pubDate={projects.data.pubDate}
              />
              <br />
            </>
          ))
        }
#

In my card.astro

#card.astro
---
const { url, image, imageUrl, alt, title, description, pubDate } = Astro.props;
import { Image } from 'astro:assets';
---

<a
  href={url}
  class="card lg:card-side bg-base-100 shadow-xl outline-dotted"
  style="text-decoration: none"
  data-astro-prefetch
>
  {image ? (
    // works as expected
    <figure>
      <img src={imageUrl} alt={alt} class="rounded-3xl p-2" />
    </figure>
    // Will throw the must be imported error
    <Image src={imageUrl} alt={alt} class="rounded-3xl p-2" />
  ) : null} 
  <div class="card-body">
    <h2 class="card-title">{title}</h2>
    <p>{description}.</p>
      {pubDate}
  </div>
</a>
#

Image's and getImage's src parameter must be an imported image or an URL, it cannot be a string filepath. Received ../images/capsule.gif.

Im not familar with schema validation or zod but is this something im missing there?

smoky umbra
light smelt
#

the image is processed when defined in the schema this way

#

i havent really seen this type of stuff before, but why do we need that image function?

#

in my case i dont need any validation of the image, so im doing

const projectsCollection = defineCollection({
  type: "content",
  schema: ({ image }) => z.object({
    title: z.string(),
    pubDate: z.string(),
    description: z.string(),
    author: z.string(),
    cover: image(),
  }),
});

and it works

#

but i dont really get why i needed the schema: ({ image }) => z.object({ part of it

hexed citrus
#

it's a bit of a technical detail, but it's because image's internal code is relative to the file being processed, so the schema has to be reran with some context

#

It's an odd pattern, but it's what Zod recommend for this usecase, so we went with it

light smelt
#

Thanks, ill just roll with it