Tag Cloud

A tag-cloud for your Astro blog

astrotagstag-cloud
Published 2022-04-12

Introduction

A common component for a blog is some kind of tag-cloud where a user can select a tag or keyword and filter the available posts by it.

Component

This component will take in the array of posts from await Astro.glob(./*.md) and it will inspect and gather tag information from each post frontmatter.

The frontmatter for my posts goes something like this:

---
layout: ./../../layouts/PostLayout.astro
title: Tag Cloud
summary: A tag-cloud for your Astro blog
published: '2022-04-12'
tags: ['astro','tags','tag-cloud']
og:
  site_name: readonlychild
  basic:
    title: Tag Cloud
    type: Article
    image: https://cdn.ixmage.com/v2/...
    description: A tag-cloud for your Astro blog
---

The relevant part for this post is the tags array that I populate while writing the post.

Code

The code for the Astro component:
/* commentary */ available

// TagCloud.astro
---
// takes in an array of posts
const posts = Astro.props.posts;
// initialize annn object to aggregate tag information
let cloud = {};
// loop posts
posts.forEach((post) => {
  // loop tags for each post
  post.frontmatter.tags.forEach((tag) => {
    // add *new* tag to map
    if (!cloud[tag]) cloud[tag] = 0;
    // increment tag count
    cloud[tag] += 1;
  });
});
// now collect tag names...
let tags = [];
// ... from cloud map properties...
for (let prop in cloud) {
  tags.push(prop);
}
---
<div style="text-align:center;">
{tags.map(tag => (
  <a href={`/blog/tag/${tag}`}><span class="badge box me-2 mb-2" style={`font-size:${cloud[tag]*2+12}px;`}>{tag}</span></a>
))}
</div>

On the markup portion, the tag names are mapped to produce a styled span for each tag. There are some bootstrap classes involved.

And there is a font-size play there to increase the tag size depending on how many times the tag appears across the posts.

Preview

cloud-preview

Usage

On my astro page that lists my blog posts, and where I use await Astro.glob('./*.md'), I import the component and pass prop posts into it

---
import BaseLayout from './../../layouts/BaseLayoutNoContainer.astro';
// more imports
import TagCloud from './../../components/TagCloud.astro';

const posts = await Astro.glob('./*.md');
// some posts filtering and sorting
---
...
<TagCloud posts={posts} />
...

Conclusion

Now you have one more piece for your Astro Blog.



Back to Post List
ok!