Skip to content

Tag list

Implementation in Starlight

  1. Create TagList component

    src/components/TagList.astro
    ---
    import { getCollection } from "astro:content";
    const docs = await getCollection("docs");
    type Docs = typeof docs;
    const docsByTags = new Map<string, Docs>();
    docs.forEach((doc) => {
    if (doc.data.tags) {
    doc.data.tags.forEach((tag: string) => {
    docsByTags.set(tag, docsByTags.get(tag) || []);
    docsByTags.get(tag)?.push(doc);
    });
    }
    });
    const comparator = new Intl.Collator("en");
    const tagsSorted = [...docsByTags.keys()].sort(comparator.compare);
    ---
    <ul>
    {
    tagsSorted.map((tag) => (
    <li>
    {tag} ({docsByTags.get(tag)?.length})
    <ul>
    {docsByTags.get(tag)?.map((doc) => (
    <li>
    <a href={`/${doc.slug}`}>{doc.data.title}</a>
    </li>
    ))}
    </ul>
    </li>
    ))
    }
    </ul>
  2. Adjust content schema

    src/content/config.ts
    import { z, defineCollection } from "astro:content";
    import { docsSchema, i18nSchema } from "@astrojs/starlight/schema";
    export const collections = {
    docs: defineCollection({
    schema: docsSchema({
    extend: z.object({
    tags: z.array(z.string()).optional(),
    }),
    }),
    }),
    i18n: defineCollection({ type: "data", schema: i18nSchema() }),
    };
  3. Use component, wherever you like

    ---
    title: Tags
    tableOfContents: false
    prev: false
    next: false
    ---
    import TagList from "@components/TagList.astro";
    <TagList />

Example

See Tags.

Further improvements

  • Page for each tag
  • Metadata for tags (color, icon)

Tag page

From starlight-blog:

  • Tag Page
  • Tag-Related Functions
  • injectRoute Example
    addIntegration({
    name: "starlight-blog-integration",
    hooks: {
    "astro:config:setup": ({ injectRoute, updateConfig }) => {
    injectRoute({
    entrypoint: "starlight-blog/routes/Tags.astro",
    pattern: "/blog/tags/[tag]",
    prerender: true,
    });
    },
    },
    });

Icons for tags

Each tag can have its own color or icon to help differentiate them visually. For example:

  • #markdown
  • #component
  • #link
  • #page
  • #Astro
  • #TypeScript