first commit
Made-with: Cursor
This commit is contained in:
84
frontend/app/blog/[slug]/page.tsx
Normal file
84
frontend/app/blog/[slug]/page.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import type { Metadata } from "next";
|
||||
import BlogPostClient from "./BlogPostClient";
|
||||
import { BlogPostingJsonLd, BreadcrumbJsonLd } from "@/components/public/JsonLd";
|
||||
|
||||
const apiUrl = process.env.NEXT_PUBLIC_API_URL || "http://localhost:4000/api";
|
||||
|
||||
async function fetchPost(slug: string) {
|
||||
try {
|
||||
const res = await fetch(`${apiUrl}/posts/${slug}`, {
|
||||
next: { revalidate: 300 },
|
||||
});
|
||||
if (!res.ok) return null;
|
||||
return res.json();
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ slug: string }>;
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
const post = await fetchPost(slug);
|
||||
if (!post) {
|
||||
return { title: "Post Not Found" };
|
||||
}
|
||||
|
||||
const description =
|
||||
post.excerpt ||
|
||||
`Read "${post.title}" on the Belgian Bitcoin Embassy blog.`;
|
||||
const author = post.authorName || "Belgian Bitcoin Embassy";
|
||||
const ogImageUrl = `/og?title=${encodeURIComponent(post.title)}&type=blog`;
|
||||
|
||||
return {
|
||||
title: post.title,
|
||||
description,
|
||||
openGraph: {
|
||||
type: "article",
|
||||
title: post.title,
|
||||
description,
|
||||
publishedTime: post.publishedAt || post.createdAt,
|
||||
authors: [author],
|
||||
images: [{ url: ogImageUrl, width: 1200, height: 630, alt: post.title }],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: post.title,
|
||||
description,
|
||||
images: [ogImageUrl],
|
||||
},
|
||||
alternates: { canonical: `/blog/${slug}` },
|
||||
};
|
||||
}
|
||||
|
||||
export default async function BlogDetailPage({ params }: Props) {
|
||||
const { slug } = await params;
|
||||
const post = await fetchPost(slug);
|
||||
|
||||
return (
|
||||
<>
|
||||
{post && (
|
||||
<>
|
||||
<BlogPostingJsonLd
|
||||
title={post.title}
|
||||
description={post.excerpt || `Read "${post.title}" on the Belgian Bitcoin Embassy blog.`}
|
||||
slug={slug}
|
||||
publishedAt={post.publishedAt || post.createdAt}
|
||||
authorName={post.authorName}
|
||||
/>
|
||||
<BreadcrumbJsonLd
|
||||
items={[
|
||||
{ name: "Home", href: "/" },
|
||||
{ name: "Blog", href: "/blog" },
|
||||
{ name: post.title, href: `/blog/${slug}` },
|
||||
]}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<BlogPostClient slug={slug} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user