Skip to content

Tags, Collections, and Slugs

Published: at 07:33 PM

I decided to add tags to my posts to make it easier for searching for specific content. I think I may have been brain dead when doing it because I walked away from the experience going, “There has to be a better way…”

Tags

I was able to easily add tags to all the markdown files, which are used to create the different posts on this site.

I figured that my tags are going to be generated based on the params sent via the site’s URL so I based my code on what I found in the Astro documents.

export async function getStaticPaths() {
  const allPosts = await Astro.glob("../../content/blog/*.md");
  const uniqueTags = [
    ...new Set(allPosts.map(post => post.frontmatter.tags).flat()),
  ];

  return uniqueTags.map(tag => {
    const filteredPosts = allPosts.filter(post =>
      post.frontmatter.tags.includes(tag)
    );

    return {
      params: { tag: tag },
      props: { posts: filteredPosts },
    };
  });
}

const { tag } = Astro.params;
const { posts } = Astro.props;

It works. Every time you visit /tags/SLUG it will generate a page that either lists all the posts with that tag or gives you a 404, depending on if you’re searching for a tag that exists or not.

404: Slug Not Found

I was able to get the root of /tags working the way I wanted. It happily lists all the tags currently on the site!

const allPosts = await Astro.glob("../../content/blog/*.md");
const tags = [...new Set(allPosts.map(post => post.frontmatter.tags).flat())];
<div class="flex justify-between">
  {tags.map(tag => (
    <p>
      <a href={`/tags/${tag}`}>{tag}</a>
    </p>
  ))}
</div>

The trouble happened when I tried to auto generate the URL to the individual articles listed in the [tag].astro file. The post.url shows as undefined. Yikes!

Collections

The blog template I am using from the default install of Astro has the blogs set up in a collection. Collections are really neat! They allow you to have groups of content visually separated and even generate routes to go with them.

It got me thinking. Why am I using Astro.glove() when I could just gather everything in the collection, thus being able to use the url Astro generates to fill in the href for that post’s link?

I spent a lot of time trying to see if I could use anything related to collections to grab that gloriously hidden url. I’m not ashamed to state that I never go it working. Instead I ran into an error I have never seen before over and over!

oo_oo is not defined

This showed up every time I was trying to console.log() anything inside getStaticPaths(). I bet there is a darn good reason for it, but I was just hoping to have a very simple way of getting this to work so I could move on other things.

I’m still really unsure what an oo_oo is! Someone suggested it was a small spider, but…

After several hours of confusion, and not real information that helped me, I decided to go back to the basics. I just added a slug to the frontmatter of all my posts. Easy enough to play with, and something that Astro understands as well.

Slug Found

Once I added the slug, it was dead simple to get the linking working properly. Hurray!

Other Thoughts

This is only brushing the surface of what I did. And I’m still really unsure what an oo_oo is! Someone suggested it was a small spider, but I can only hope it’s not! Unless it’s Lucas. Lucas is always welcome. As a small reminder to myself, I looked at getStaticProps() and even regex and splice() as methods to get things from the post.file value, but in the end, sometimes KISS is the best principle to follow. You can always get fancy later.