Skip to content

Commit b4e6080

Browse files
committed
feat(metadata): add generateMetadata function for resource and category pages
1 parent 594eb7f commit b4e6080

File tree

4 files changed

+70
-4
lines changed

4 files changed

+70
-4
lines changed

src/app/(public)/resources/[slug]/page.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,49 @@
11
import { notFound } from "next/navigation";
22
import { getResourceBySlug } from "@/actions/resources";
33
import { ResourceDetail } from "@/components/resources";
4+
import { Metadata } from "next";
5+
import { PROJECT_NAME } from "@/config/constants";
46

57
type Props = {
68
params: { slug: string };
79
};
810

11+
export async function generateMetadata({ params }: Props): Promise<Metadata> {
12+
const { slug } = await params;
13+
const resource = await getResourceBySlug(slug);
14+
15+
if (!resource) {
16+
return {
17+
title: "Resource not found",
18+
description: "The resource you are looking for does not exist.",
19+
robots: "noindex, nofollow",
20+
};
21+
}
22+
23+
return {
24+
title: `${resource.name} - ${PROJECT_NAME}`,
25+
description: resource.description,
26+
openGraph: {
27+
title: `${resource.name} - ${PROJECT_NAME}`,
28+
description: resource.description,
29+
images: [
30+
{
31+
url: resource.image,
32+
width: 1200,
33+
height: 630,
34+
alt: resource.name,
35+
},
36+
],
37+
},
38+
twitter: {
39+
card: "summary_large_image",
40+
title: `${resource.name} - ${PROJECT_NAME}`,
41+
description: resource.description,
42+
images: [resource.image],
43+
},
44+
};
45+
}
46+
947
export default async function ResourceDetailPage({ params }: Props) {
1048
const { slug } = await params;
1149
const resource = await getResourceBySlug(slug);

src/app/(public)/resources/categories/[category]/page.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,35 @@
1+
import type { Metadata } from "next";
2+
13
import { getResourcesByCategory } from "@/actions/resources";
24
import { ResourceList } from "@/components/resources";
35
import { EmptyList } from "@/components/layout";
46
import { Heading } from "@/components/ui";
7+
import { PROJECT_NAME } from "@/config/constants";
8+
import { formatSlugToTitle } from "@/lib/utils";
59

610
export const dynamic = "force-dynamic";
711

812
type Props = {
913
params: { category: string };
1014
};
1115

16+
export async function generateMetadata({ params }: Props): Promise<Metadata> {
17+
const { category } = await params;
18+
19+
if (!category) {
20+
return {
21+
title: "Category not found",
22+
description: "The category you are looking for does not exist.",
23+
robots: "noindex, nofollow",
24+
};
25+
}
26+
27+
return {
28+
title: `${formatSlugToTitle(category)} - ${PROJECT_NAME}`,
29+
description: `Explore all the resources by category: ${category}`,
30+
};
31+
}
32+
1233
export default async function ResourcesByCategoryPage({ params }: Props) {
1334
const { category } = await params;
1435
const resources = await getResourcesByCategory(category);
@@ -23,7 +44,7 @@ export default async function ResourcesByCategoryPage({ params }: Props) {
2344
return (
2445
<main className="max-w-screen-xl mx-auto p-4 flex flex-col gap-4">
2546
<Heading
26-
title={category}
47+
title={formatSlugToTitle(category)}
2748
subtitle="Explore all the resources by category"
2849
/>
2950
{renderResources()}

src/components/resources/resource-card.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ export default function ResourceCard({ resource }: Props) {
1616
<Card
1717
isBlurred
1818
radius="none"
19-
className="bg-white dark:bg-neutral-950 active:bg-neutral-800 transition-colors duration-1000 !outline-none shadow-none rounded-xl p-2 border-2 border-neutral-200 dark:border-neutral-800"
19+
className="bg-white dark:bg-neutral-950 active:bg-neutral-800 transition-colors duration-1000 !outline-none shadow-none rounded-xl border-2 border-neutral-200 dark:border-neutral-800"
2020
>
21-
<figure className="relative border-2 border-neutral-200 dark:border-neutral-800 rounded-md overflow-hidden">
21+
<figure className="relative border-b-2 border-neutral-200 dark:border-neutral-800 overflow-hidden">
2222
<span className="hidden group-hover:block absolute top-2 right-2 bg-neutral-950 dark:bg-white text-neutral-950 px-2 py-1 rounded-lg text-xs z-50">
2323
{resource.category?.name ?? "Uncategorized"}
2424
</span>

src/lib/utils.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1-
export function capitalize(str: string) {
1+
export function capitalize(str: string): string {
22
return str.charAt(0).toUpperCase() + str.slice(1);
33
}
4+
5+
export function formatSlugToTitle(slug: string): string {
6+
return slug
7+
.split("-")
8+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
9+
.join(" ");
10+
}

0 commit comments

Comments
 (0)