import { notFound } from "next/navigation"; import type { Metadata } from "next"; import { loadDictionary } from "@allai/i18n/server"; import { locales, resolveLocale } from "@/config/i18n"; import { getBlogPosts } from "@/features/marketing/blogData"; import { absoluteUrl, buildCanonical, buildLocaleAlternates, buildOpenGraph, buildTwitterCard } from "@/seo/seoUtils"; const PATH_PREFIX = "/blog" as const; type PageProps = { params: { locale: string; slug: string }; }; export function generateStaticParams() { return locales.flatMap((locale) => getBlogPosts(locale).map((post) => ({ locale, slug: post.slug }))); } export async function generateMetadata({ params }: PageProps): Promise { const locale = resolveLocale(params.locale); if (!locales.includes(locale)) { return { title: "Article not found" }; } const dictionary = await loadDictionary(locale); const post = getBlogPosts(locale).find((item) => item.slug === params.slug); if (!post) { const notFoundTitle = locale === "ru" ? `Статья не найдена | ${dictionary.common.brandLong ?? dictionary.common.brandShort}` : locale === "es" ? `Artículo no encontrado | ${dictionary.common.brandLong ?? dictionary.common.brandShort}` : locale === "pt" ? `Artigo não encontrado | ${dictionary.common.brandLong ?? dictionary.common.brandShort}` : `Article not found | ${dictionary.common.brandLong ?? dictionary.common.brandShort}`; return { title: notFoundTitle }; } const title = `${post.title} | ${dictionary.common.brandLong ?? dictionary.common.brandShort}`; const description = post.excerpt; const path = `${PATH_PREFIX}/${post.slug}`; return { title, description, alternates: { canonical: buildCanonical(locale, path), languages: buildLocaleAlternates(path) }, openGraph: { ...buildOpenGraph({ locale, title, description, path, type: "article" }), publishedTime: post.publishedAt, section: post.category }, twitter: buildTwitterCard({ title, description }) }; } export default async function BlogArticlePage({ params }: PageProps) { const locale = resolveLocale(params.locale); if (!locales.includes(locale)) { notFound(); } const dictionary = await loadDictionary(locale); const post = getBlogPosts(locale).find((item) => item.slug === params.slug); if (!post) { notFound(); } const canonical = buildCanonical(locale, `${PATH_PREFIX}/${post.slug}`); const publisher = { "@type": "Organization", name: dictionary.common.brandLong ?? dictionary.common.brandShort, logo: { "@type": "ImageObject", url: absoluteUrl("/favicon.ico") } }; const structuredData = { "@context": "https://schema.org", "@type": "BlogPosting", headline: post.title, description: post.excerpt, author: publisher, publisher, datePublished: post.publishedAt, dateModified: post.publishedAt, articleSection: post.category, mainEntityOfPage: canonical, url: canonical, inLanguage: locale, wordCount: post.content.replace(/<[^>]+>/g, " ").trim().split(/\s+/).length }; return (