Files
BelgianBitcoinEmbassy/frontend/app/blog/[slug]/page.tsx
Michilis 8cdf0231ce fix(frontend): resolve API base URL at request time for production
Use same-origin /api in the browser so builds are not stuck with baked-in
localhost. Server-side fetches use INTERNAL_API_URL, NEXT_PUBLIC_API_URL, or
loopback. Centralize logic in lib/api-base.ts.

Made-with: Cursor
2026-04-01 19:52:54 +00:00

84 lines
2.2 KiB
TypeScript

import type { Metadata } from "next";
import BlogPostClient from "./BlogPostClient";
import { BlogPostingJsonLd, BreadcrumbJsonLd } from "@/components/public/JsonLd";
import { apiUrl } from "@/lib/api-base";
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} />
</>
);
}