import React from "react"; import type { Metadata } from "next"; import { notFound } from "next/navigation"; import { MDXRemote } from "next-mdx-remote/rsc"; import { getArticleBySlug, getAllArticles, getAlternatesArticle } from "@/lib/blog/get-articles"; import { ArticleHero } from "@/app/[locale]/blog/[slug]/_components/ArticleHero"; import { ArticleSummary } from "@/app/[locale]/blog/[slug]/_components/ArticleSummary"; import { locales } from "@/middleware"; import Link from "next/link"; import { MermaidDiagram } from "@/components/mdx/MermaidDiagram"; type props = { params: Promise<{ locale: string; slug: string; }>; }; const siteUrl = (process.env.NEXT_PUBLIC_SITE_URL ?? "https://matheoguilbert.fr").replace(/\/$/, ""); export async function generateMetadata({ params }: props): Promise { const { locale, slug } = await params; const article = getArticleBySlug(slug, locale); if (!article || !article.ready) { return {}; } const languageAlternates = getAlternatesArticle(article); const absoluteLanguageAlternates = Object.fromEntries( Object.entries(languageAlternates).map(([language, path]) => [ language, `${siteUrl}${path}`, ]) ); const url = `${siteUrl}/${locale}/blog/${slug}`; const title = article.title; const description = article.description; const imageUrl = article.cover ? article.cover.startsWith("http") ? article.cover : `${siteUrl}${article.cover}` : `${siteUrl}/og-image.jpg`; return { title, description, alternates: { canonical: url, languages: { ...absoluteLanguageAlternates, "x-default": url, }, }, openGraph: { title, description, url, siteName: "Mathéo Guilbert", type: "article", locale, publishedTime: article.date, images: [ { url: imageUrl, width: 1200, height: 630, alt: title, }, ], }, twitter: { card: "summary_large_image", title, description, images: [imageUrl], }, robots: { index: true, follow: true, }, }; } export function generateStaticParams() { const paths: { locale: string; slug: string }[] = []; locales.forEach((locale) => { getAllArticles(locale).forEach((article) => { paths.push({ locale, slug: article.slug, }); }); }); return paths; } const mdxComponents = { a: (props: any) => { const href = props.href; const isInternalLink = href && (href.startsWith('/') || href.startsWith('#')); if (isInternalLink) { return ( {props.children} ); } return ( {props.children} ); }, pre: (props: React.ComponentPropsWithoutRef<"pre"> & { children?: React.ReactElement<{ className?: string; children?: React.ReactNode }> }) => { const child = props.children; const isMermaid = child?.props?.className?.includes("language-mermaid"); if (isMermaid && child) { const code = String(child.props.children).trimEnd(); return ; } return
;
    },
};

export default async function ArticlePage({ params }: props) {
    const { locale, slug } = await params;
    const article = getArticleBySlug(slug, locale);

    if (!article || !article.ready) {
        notFound();
    }

    const articleUrl = `${siteUrl}/${locale}/blog/${slug}`;

    const imageUrl = article.cover
        ? article.cover.startsWith("http")
            ? article.cover
            : `${siteUrl}${article.cover}`
        : `${siteUrl}/og-image.jpg`;

    const jsonLd = {
        "@context": "https://schema.org",
        "@type": "BlogPosting",
        headline: article.title,
        description: article.description,
        image: imageUrl,
        datePublished: article.date,
        dateModified: article.date,
        author: {
            "@type": "Person",
            name: "Mathéo Guilbert",
            url: siteUrl,
        },
        publisher: {
            "@type": "Person",
            name: "Mathéo Guilbert",
            url: siteUrl,
        },
        mainEntityOfPage: {
            "@type": "WebPage",
            "@id": articleUrl,
        },
    };

    return (