#mdx blog

24 messages · Page 1 of 1 (latest)

river escarp
#

Guys I wana make a mdx blog using astro , what should be schema for the collection? I have folders in blogs directory inside content , the folders inside blogs dir are blog names with index.mdx and banner.png ,how can I make my collection gets banner.png passed automatically?

native roverBOT
#

Hi @river escarp. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To create a blog using Astro with MDX, you need to define a collection for your blog posts. The collection should be defined in a config.ts file inside your src/content/ directory.

Here is an example of how you can define a collection for your blog posts:

import { z, defineCollection } from "astro:content";

const blogCollection = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    pubDate: z.date(),
    description: z.string(),
    author: z.string(),
    image: z.object({
      url: z.string(),
      alt: z.string()
    }),
    tags: z.array(z.string())
  })
});

export const collections = { blog: blogCollection };

In this example, the schema property is used to define the structure of the frontmatter for your blog posts. The image property is an object that includes url and alt properties. You can adjust this schema to fit the structure of your own frontmatter.

Regarding your question about automatically passing banner.png, you can use the image() schema helper in the experimental assets API. This helper has been moved to a callback where the schema is defined in Astro 2.2. Here is an example:

import { defineCollection, z } from "astro:content"

const blog = defineCollection({
 schema: ({ image }) =>
 z.object({
 image: image().refine((img) => img.width >= 200, {
 message: "image too small",
 }),
 }),
})

In this example, the image() helper is used to validate the image dimensions. You can adjust the refine function to fit your own requirements.

Please note that this feature is experimental and may change in future releases. You can find more information about this in the Astro 2.2 blog post (https://astro.build/blog/astro-220/).

#

@river escarp kapa.ai is still learning and improving, please let us know how it did by reacting below

river escarp
#

@native rover can u explain it?

import { defineCollection, z } from "astro:content";

type Schema = Parameters<typeof defineCollection>[0]["schema"];

const blogSchema: Schema = ({ image }) => {
  return z.object({
    title: z.string(),
    date: z.coerce.date(),
    description: z.string(),
    tags: z.array(z.string()),
    draft: z.boolean().default(false),
    banner: image(),
    imageTop: z
      .object({
        src: z.string(),
      })
      .optional(),
  });
};

export type BlogSchema = z.infer<ReturnType<typeof blogSchema>>;

const blogCollection = defineCollection({
  type: "content",
  schema: ({ image }) => blogSchema({ image }),
  /* ... */
});
// 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 = {
  blog: blogCollection,
};
native roverBOT
#

Let me check the knowledge base for you. One moment! :books:

#

This script is defining a collection for a blog in Astro using TypeScript. Let's break it down:

  1. Importing the necessary functions:
import { defineCollection, z } from "astro:content";

defineCollection is a function from Astro that allows you to define a content collection. z is a library for building schemas.

  1. Defining the schema for the blog:
type Schema = Parameters<typeof defineCollection>[0]["schema"];

const blogSchema: Schema = ({ image }) => {
  return z.object({
    title: z.string(),
    date: z.coerce.date(),
    description: z.string(),
    tags: z.array(z.string()),
    draft: z.boolean().default(false),
    banner: image(),
    imageTop: z
      .object({
        src: z.string(),
      })
      .optional(),
  });
};

Here, a TypeScript type Schema is defined to represent the schema of a collection. Then, blogSchema is defined as a function that returns a z.object representing the structure of a blog post. This includes properties like title, date, description, tags, draft, banner, and imageTop. The image() function is used to handle images in the schema.

  1. Defining the blog collection:
const blogCollection = defineCollection({
  type: "content",
  schema: ({ image }) => blogSchema({ image }),
  /* ... */
});

Here, defineCollection is used to define the blog collection. The type is set to "content" and the schema is set to the blogSchema defined earlier.

  1. Exporting the collections:
export const collections = {
  blog: blogCollection,
};

Finally, the collections are exported. In this case, there is only one collection: blog.

#

This script is a way to define the structure of your blog posts and validate them using a schema. It's a powerful way to ensure that your content has the correct structure and types.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@river escarp kapa.ai is still learning and improving, please let us know how it did by reacting below

river escarp
native roverBOT
#

Let me check the knowledge base for you. One moment! :books:

#

The image is passed as a parameter to the blogSchema function. This function is then used as the schema property in the defineCollection function.

Here's the relevant part of the code:

const blogSchema: Schema = ({{ image }}) => {{
  return z.object({{
    // ...
    banner: image(),
    // ...
  }});
}};

const blogCollection = defineCollection({{
  type: "content",
  schema: ({{ image }}) => blogSchema({{ image }}),
  /* ... */
}});

In the blogSchema function, image is used as a function to handle the banner property. This image function comes from the astro:content module and is used to handle images in the schema.

When the blogSchema function is used as the schema property in the defineCollection function, the image function is passed as an argument. This is how the image function is passed to the blogSchema function.

This setup allows Astro to handle images in your blog posts' frontmatter. The image function will validate the image and provide metadata about it, such as its dimensions. This is particularly useful if you want to ensure that all images in your blog posts meet certain criteria, such as a minimum width.

For more information about handling images in Astro, you can refer to the Astro documentation (https://docs.astro.build/en/guides/images/).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@river escarp kapa.ai is still learning and improving, please let us know how it did by reacting below

river escarp
#

@native rover the image argument which you destruct gets automatically passed?

native roverBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Yes, the image argument is automatically passed to the schema function by Astro. When you define a collection using defineCollection, Astro will pass an image function to the schema function. This image function is used to handle images in your frontmatter.

Here's the relevant part of the code:

const blogSchema: Schema = ({{ image }}) => {{
  // ...
}};

const blogCollection = defineCollection({{
  type: "content",
  schema: ({{ image }}) => blogSchema({{ image }}),
  /* ... */
}});

In this code, defineCollection is calling blogSchema with an image function as an argument. This image function comes from Astro and is used to handle images in your frontmatter.

This setup allows Astro to automatically handle images in your blog posts. You don't need to manually pass the image function to blogSchema; Astro does this for you.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@river escarp kapa.ai is still learning and improving, please let us know how it did by reacting below

river escarp
native roverBOT
#

Let me check the knowledge base for you. One moment! :books:

#

The image function in the context of Astro's content collections is used to handle a single image per call. It's designed to work with a single image field in your frontmatter.

Here's how it's used in the schema:

const blogSchema: Schema = ({{ image }}) => {{
  return z.object({{
    // ...
    banner: image(),
    // ...
  }});
}};

In this example, image() is used to handle the banner image. If you have multiple image fields in your frontmatter, you would use image() for each one:

const blogSchema: Schema = ({{ image }}) => {{
  return z.object({{
    banner: image(),
    thumbnail: image(),
    // ...
  }});
}};

In this case, image() is used separately for the banner and thumbnail fields. Each call to image() handles a single image.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@river escarp kapa.ai is still learning and improving, please let us know how it did by reacting below

river escarp
#

@native rover how will I render mdx in my [slug].astro?

native roverBOT
#

Let me check the knowledge base for you. One moment! :books: