#Import a variable category of blog posts similar to Astro.glob

4 messages · Page 1 of 1 (latest)

glass basin
#

Here's a simplified example. I have a blog. That blog has 3 content collections: guides, news and interviews. Each one contains markdown (.md) posts.
I have the following file structure:
--src
|--content
|--guides
|--news
|--interviews

I have a component that displays posts from a category. When I call the component, I want to pass the category as a prop and load the posts of that category only.
However, the problem is that Astro.glob() doesn't accept variables.

What's the flow in my structure and logic and how to achieve this better?

eager quiverBOT
#

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

#

You're correct that Astro.glob() does not support dynamic variables or string interpolation due to a limitation of Vite’s import.meta.glob() function, which only supports static string literals. This is not a bug in Astro, but a limitation of the underlying technology it uses for this feature (source (https://docs.astro.build/en/guides/troubleshooting/#astroglob---no-matches-found)).

However, you can use a workaround to import a larger set of files that includes all the files you need using Astro.glob(), and then filter them based on your requirements. Here's an example:

---
const { category } = Astro.props;
const allPosts = await Astro.glob('../content/**/*.md');
const categoryPosts = allPosts.filter(post => post.file.includes(`../content/${category}/`));
---

In this example, Astro.glob() is used to import all markdown files from the content directory and its subdirectories. Then, the filter() method is used to select only the posts that belong to the specified category.

However, a more efficient way to handle this would be to use Astro's getCollection() API, which is designed for loading multiple files from content collections. This would allow you to directly query the collection corresponding to the category you're interested in, without having to load and filter all posts. Here's how you could do it:

---
import { getCollection } from "astro:content";
const { category } = Astro.props;
const categoryPosts = await getCollection(category);
---
#

In this example, getCollection() is used to load all posts from the specified category. The category is passed as a prop to the component and used as the argument to getCollection(). This will return all posts from the corresponding content collection (source (https://docs.astro.build/en/tutorials/add-content-collections/#replace-astroglob-with-getcollection)).

Please note that when using collections, each post object will have a page slug, not a full URL, and you will find your frontmatter values on the data property of each object (source (https://docs.astro.build/en/tutorials/add-content-collections/#replace-astroglob-with-getcollection)).

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