import { Metadata } from 'next' import { notFound } from 'next/navigation' import { blogPosts } from '@/lib/blogPosts' import { BlogPostTemplate } from '@/components/blog/BlogPostTemplate' import { getHreflangAlternates } from '@/lib/localeRoutes' interface Props { params: Promise<{ slug: string }> } export async function generateStaticParams() { return Object.keys(blogPosts).map((slug) => ({ slug })) } export async function generateMetadata({ params }: Props): Promise { const { slug } = await params const post = blogPosts[slug] if (!post) return {} const languages = getHreflangAlternates(post.canonical) return { title: post.metaTitle, description: post.metaDescription, // Selbstreferenzierender Canonical. Wichtig für die Syndication: Wenn der // Beitrag auf Medium, DEV.to oder LinkedIn zweitveröffentlicht wird, muss // dort ein rel=canonical auf genau diese URL zeigen. alternates: { canonical: post.canonical, ...(languages && { languages }), }, openGraph: { type: 'article', title: post.metaTitle, description: post.metaDescription, url: post.canonical, publishedTime: post.publishedAtIso, modifiedTime: post.updatedAtIso || post.publishedAtIso, authors: [post.author.name], images: [{ url: post.heroImage, width: 1200, height: 630, alt: post.heroImageAlt }], }, twitter: { card: 'summary_large_image', title: post.metaTitle, description: post.metaDescription, images: [post.heroImage], }, } } export default async function BlogPostPage({ params }: Props) { const { slug } = await params const post = blogPosts[slug] if (!post) { notFound() } return }