diff --git a/src/app/blog/[slug]/page.tsx b/src/app/blog/[slug]/page.tsx
index 998fcc0..8ccddd6 100644
--- a/src/app/blog/[slug]/page.tsx
+++ b/src/app/blog/[slug]/page.tsx
@@ -1,14 +1,59 @@
-'use client'
-import { useParams } from 'next/navigation'
-import PublicLayout from '@/components/public/PublicLayout'
-import BlogPostPage from '@/components/public/BlogPostPage'
+import type { Metadata } from 'next'
+import BlogPostPageClient from '@/components/public/BlogPostPageClient'
-export default function PostPage() {
- const params = useParams()
- const slug = params.slug as string
- return (
-
-
-
- )
+const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://example.com'
+const SITE_NAME = process.env.NEXT_PUBLIC_SITE_NAME || 'My Personal Site'
+
+interface Props {
+ params: { slug: string }
+}
+
+/**
+ * NOTE: For full dynamic metadata you would fetch the post here.
+ * Since this CMS appears to be client-side/localStorage based,
+ * we provide sensible per-slug defaults and let the client
+ * component inject JSON-LD after hydration.
+ */
+export async function generateMetadata({ params }: Props): Promise {
+ const slug = params.slug
+ const title = slug
+ .split('-')
+ .map((w: string) => w.charAt(0).toUpperCase() + w.slice(1))
+ .join(' ')
+
+ const description = `Read "${title}" on ${SITE_NAME}.`
+ const canonicalUrl = `${SITE_URL}/blog/${slug}`
+ const ogImageUrl = `/api/og?slug=${encodeURIComponent(slug)}`
+
+ return {
+ title,
+ description,
+ alternates: {
+ canonical: canonicalUrl,
+ },
+ openGraph: {
+ type: 'article',
+ url: canonicalUrl,
+ title: `${title} | ${SITE_NAME}`,
+ description,
+ images: [
+ {
+ url: ogImageUrl,
+ width: 1200,
+ height: 630,
+ alt: title,
+ },
+ ],
+ },
+ twitter: {
+ card: 'summary_large_image',
+ title: `${title} | ${SITE_NAME}`,
+ description,
+ images: [ogImageUrl],
+ },
+ }
+}
+
+export default function PostPage({ params }: Props) {
+ return
}