import { notFound, redirect } from 'next/navigation'; import JsonLd from '@/components/JsonLd'; import { SITE_URL } from '@/lib/schema'; import { getPostBySlug, getAdjacentPosts, getReadingTime, extractLexicalHeadings, getPostSlugs, } from '@/lib/blog'; import { Metadata } from 'next'; import Link from 'next/link'; import Image from 'next/image'; import PostNavigation from '@/components/blog/PostNavigation'; import PowerCTA from '@/components/blog/PowerCTA'; import TableOfContents from '@/components/blog/TableOfContents'; import { Heading } from '@/components/ui'; import { setRequestLocale } from 'next-intl/server'; import BlogEngagementTracker from '@/components/analytics/BlogEngagementTracker'; // Payload CMS Imports import PayloadRichText from '@/components/PayloadRichText'; interface BlogPostProps { params: Promise<{ locale: string; slug: string; }>; } export async function generateMetadata({ params }: BlogPostProps): Promise { const { locale, slug } = await params; const post = await getPostBySlug(slug, locale); if (!post) return {}; const slugs = await getPostSlugs(slug, locale); const deSlug = slugs?.de || post.slug; const enSlug = slugs?.en || post.slug; const description = post.frontmatter.excerpt || ''; return { title: post.frontmatter.title, description: description, alternates: { canonical: `${SITE_URL}/${locale}/blog/${post.slug}`, languages: { de: `${SITE_URL}/de/blog/${deSlug}`, en: `${SITE_URL}/en/blog/${enSlug}`, 'x-default': `${SITE_URL}/en/blog/${enSlug}`, }, }, openGraph: { title: `${post.frontmatter.title} | KLZ Cables`, description: description, type: 'article', publishedTime: post.frontmatter.date, authors: ['KLZ Cables'], url: `${SITE_URL}/${locale}/blog/${post.slug}`, }, twitter: { card: 'summary_large_image', title: `${post.frontmatter.title} | KLZ Cables`, description: description, }, }; } export default async function BlogPost({ params }: BlogPostProps) { const { locale, slug } = await params; setRequestLocale(locale); const post = await getPostBySlug(slug, locale); if (!post) { notFound(); } // If the user accessed this post using a slug from a different locale // (e.g. via the generic language switcher), redirect them to the correct localized slug URL if (post.slug && post.slug !== slug) { redirect(`/${locale}/blog/${post.slug}`); } const { prev, next, isPrevRandom, isNextRandom } = await getAdjacentPosts(post.slug, locale); // Convert Lexical content into a plain string to estimate reading time roughly // Extract headings for TOC const headings = extractLexicalHeadings(post.content?.root || post.content); // Convert Lexical content into a plain string to estimate reading time roughly const rawTextContent = JSON.stringify(post.content); return (
{/* Featured Image Header */} {post.frontmatter.featuredImage ? (
{post.frontmatter.title}
{/* Title overlay on image */}
{post.frontmatter.category && (
{post.frontmatter.category}
)} {post.frontmatter.title}
{getReadingTime(rawTextContent)} min read {(new Date(post.frontmatter.date) > new Date() || post.frontmatter.public === false) && ( <> Draft Preview )}
) : (
{post.frontmatter.category && (
{post.frontmatter.category}
)} {post.frontmatter.title}
{getReadingTime(rawTextContent)} min read {(new Date(post.frontmatter.date) > new Date() || post.frontmatter.public === false) && ( <> Draft Preview )}
)} {/* Main Content Area with Sticky Narrative Layout */}
{/* Left Column: Content */}
{/* Excerpt/Lead paragraph if available */} {post.frontmatter.excerpt && (

{post.frontmatter.excerpt}

)} {/* Main content with enhanced styling rendering Payload Lexical */}
{/* Power CTA */}
{/* Post Navigation */}
{/* Back to blog link */}
{locale === 'de' ? 'Zurück zur Übersicht' : 'Back to Overview'}
{/* Right Column: Sticky Sidebar - TOC */}
{/* Structured Data */}
); }