From 9b5fee37e2415f3e365558ad5ab53819d63065aa Mon Sep 17 00:00:00 2001 From: HangerThem Date: Tue, 4 Aug 2026 08:06:05 +0200 Subject: [PATCH] Added tag pages --- .../categories/[categorySlug]/page.tsx | 2 +- app/(withRecent)/categories/page.tsx | 2 +- app/(withRecent)/page.tsx | 2 +- app/(withRecent)/tags/[tagSlug]/page.tsx | 62 ++++++++++++++ app/(withRecent)/tags/page.tsx | 83 +++++++++++++++++++ app/posts/[slug]/page.tsx | 2 +- components/layout/Sidebar.tsx | 5 +- components/post/RecentlyUpdatedPosts.tsx | 2 +- lib/tags.ts | 46 ++++++++++ 9 files changed, 200 insertions(+), 6 deletions(-) create mode 100644 app/(withRecent)/tags/[tagSlug]/page.tsx create mode 100644 app/(withRecent)/tags/page.tsx create mode 100644 lib/tags.ts diff --git a/app/(withRecent)/categories/[categorySlug]/page.tsx b/app/(withRecent)/categories/[categorySlug]/page.tsx index 3950a14..8ba8c71 100644 --- a/app/(withRecent)/categories/[categorySlug]/page.tsx +++ b/app/(withRecent)/categories/[categorySlug]/page.tsx @@ -48,7 +48,7 @@ export default async function CategoryPage({ params }: CategoryPageProps) { } return ( -
+

Category: {category}

    {posts.map((post) => ( diff --git a/app/(withRecent)/categories/page.tsx b/app/(withRecent)/categories/page.tsx index 419562f..4a45c98 100644 --- a/app/(withRecent)/categories/page.tsx +++ b/app/(withRecent)/categories/page.tsx @@ -33,7 +33,7 @@ export default function CategoriesPage() { const categoryNames = Object.keys(categories) return ( -
    +
    ~/categories
      diff --git a/app/(withRecent)/page.tsx b/app/(withRecent)/page.tsx index 4d1476a..b407eb1 100644 --- a/app/(withRecent)/page.tsx +++ b/app/(withRecent)/page.tsx @@ -11,7 +11,7 @@ export default function BlogIndex() { } return ( -
      +
      {posts.length === 0 ? (
      diff --git a/app/(withRecent)/tags/[tagSlug]/page.tsx b/app/(withRecent)/tags/[tagSlug]/page.tsx new file mode 100644 index 0000000..1e26684 --- /dev/null +++ b/app/(withRecent)/tags/[tagSlug]/page.tsx @@ -0,0 +1,62 @@ +import { metadata } from '@/app/metadata' +import { getAllTags, getPostsByTag, getTagBySlug } from '@/lib/tags' +import type { Metadata } from 'next' +import Link from 'next/link' + +type TagPageProps = { + params: Promise<{ + tagSlug: string + }> +} + +export async function generateStaticParams() { + const tags = getAllTags() + return Object.keys(tags).map((tag) => ({ + tagSlug: tag, + })) +} + +export async function generateMetadata({ params }: TagPageProps): Promise { + const { tagSlug } = await params + const tag = getTagBySlug(tagSlug) + + return { + title: `${tag} | ${metadata.title!.toString()}`, + description: 'List of posts in this tag', + openGraph: { + type: 'website', + title: `${tag} | ${metadata.title!.toString()}`, + description: 'List of posts in this tag', + url: process.env.SITE_URL + `/tags/${tagSlug}`, + siteName: metadata.title!.toString(), + }, + } +} + +export default async function TagPage({ params }: TagPageProps) { + const { tagSlug } = await params + const posts = getPostsByTag(tagSlug) + const tag = getTagBySlug(tagSlug) + + if (!tag) { + return ( +
      +

      Tag not found

      + Back to tags +
      + ) + } + + return ( +
      +

      Tag: {tag}

      +
        + {posts.map((post) => ( +
      • + {post.title} +
      • + ))} +
      +
      + ) +} diff --git a/app/(withRecent)/tags/page.tsx b/app/(withRecent)/tags/page.tsx new file mode 100644 index 0000000..8837328 --- /dev/null +++ b/app/(withRecent)/tags/page.tsx @@ -0,0 +1,83 @@ +import { getAllTags } from '@/lib/tags' +import { getAllPostsMeta } from '@/lib/posts' +import { slugify } from '@/utils/slug' +import type { Metadata } from 'next' +import Link from 'next/link' +import { metadata } from '@/app/metadata' +import { dateFormatter } from '@/utils/time' + +export async function generateStaticParams() { + const tags = getAllTags() + return Object.keys(tags).map((tag) => ({ + tagSlug: tag, + })) +} + +export async function generateMetadata(): Promise { + return { + title: `Tags | ${metadata.title!.toString()}`, + description: 'List of tags', + openGraph: { + type: 'website', + title: `Tags | ${metadata.title!.toString()}`, + description: 'List of tags', + url: process.env.SITE_URL + '/tags', + siteName: metadata.title!.toString(), + }, + } +} + +export default function TagsPage() { + const tags = getAllTags() + const posts = getAllPostsMeta() + const tagNames = Object.keys(tags) + + return ( +
      +
      ~/tags
      + +
        + {tagNames.map((tag) => { + const tagPosts = posts.filter((post) => post.tags && post.tags.includes(tag)) + + return ( +
      • + + + {tag} + + ({tagPosts.length}) + + +
          + {tagPosts.map((post) => ( +
        • + + + {post.title} + + {post.date && ( + + )} + +
        • + ))} +
        +
      • + ) + })} +
      +
      + ) +} diff --git a/app/posts/[slug]/page.tsx b/app/posts/[slug]/page.tsx index 0c9f076..29790fd 100644 --- a/app/posts/[slug]/page.tsx +++ b/app/posts/[slug]/page.tsx @@ -44,7 +44,7 @@ export default async function Post({ params }: { params: Promise<{ slug: string return (
      -
      +
      {meta.category && ( Commit: - + {gitCommitHash.slice(0, 7)}
      diff --git a/components/post/RecentlyUpdatedPosts.tsx b/components/post/RecentlyUpdatedPosts.tsx index d4be1b0..c719590 100644 --- a/components/post/RecentlyUpdatedPosts.tsx +++ b/components/post/RecentlyUpdatedPosts.tsx @@ -4,7 +4,7 @@ import Link from 'next/link' export function RecentlyUpdatedPosts() { const posts = getAllPostsMeta() return ( -