This month’s Virtual Coffee challenge is Build in Public. And I wanted to kick things off with some website updates. I’ve been meaning to add tags to my site for a long time. After poking around at other people’s sites, I decided to switch from the concept of tagging to the concept of topics. While the naming is different the process to adding topics was the same. In this post I want to share how I added topics, what I learnt, and what’s next.
How I added topics to my site
I mainly followed the Astro guide on building a tag index page.
Firstly, I created this structure in my project:
pages/
topics/
[topic].astro
index.astro
index.astro
is rendered when you go to /topics
(example link).
[topic].astro
is rendered when you go to /topics/:topic
. Where :topic
is something I define in my blog posts. Example, topics/api%20design/
(example link).
I then added the topics
field to my front matter yml in my blog posts:
---
pubDate: 2023-04-05
updatedDate: 2023-04-05
title: "template"
description: "A template"
draft: true
topics: []
---
Added topics
key in my config.ts
file (source code)
topics: z
.array(z.string())
.optional()
.default([])
Finally, to display the topics on my blog post, I made a component that is pulled into the Blog Post Layout:
...
{topics && topics.length > 0 && <TopicList topics={topics} />}
...
---
const { topics } = Astro.props;
---
<p class="flex space-x-3">
{topics.map((topic: string) => (
<a href={`/topics/${topic}`}>{topic}</a>
))}
</p>
Deep dive (aka what did I learn)
Digging into the index.astro
and [topic].astro
files a bit more.
index.astro
The way we get a list of topics to display on the /topic
page is through this code (source code):
const posts = (await getCollection('blog'))
const topics = [...new Set(posts.flatMap((post) => post.data.topics))];
This line will get all my posts from my blog folder, pull out all of the topics, and return an array of topics with no duplicates.
[topic].astro
To generate the corresponding topic endpoints like /topic/api%20design/
I needed to modify the getStaticPaths()
function in the [topic].astro
. (source code). I forgot to modify it originally, and I was very confused when I kept getting a 404 not found error when trying to navigate to a topic page 🤦🏻!
export async function getStaticPaths() {
const posts = (await getCollection('blog'))
const topics = [...new Set(posts.flatMap((post) => post.data.topics))];
return topics.map((topic) => ({
params: { topic }
}));
}
getStaticPaths() is an Astro function that Astro uses to generate each page at build time. It returns an array that looks something like this:
[
{ params: {topic: "API Design"} },
{ params: {topic: "Productivity"} }
]
What’s next
I’m not super happy with how my topics are styled. But I’m also not sure how I would style them - I’m open to suggestions! Next up for me is writing an About me page. I don’t know why but I find it incredibly hard to write! I’ll be chugging away at it while trying to come up with a better styling in the meantime.