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.
Top comments (0)