import Link from "next/link"; import { notFound } from "next/navigation"; import type { Metadata } from "next"; import { MDXRemote } from "next-mdx-remote/rsc"; import remarkGfm from "remark-gfm"; import { Newsletter } from "../../components/forms/Newsletter"; import { getAdjacentPosts, getAllPosts, getPost } from "@/lib/devblog"; import { formatDate, readingTime } from "@/lib/format"; import { games } from "@/lib/games"; import { SITE_URL, LOGO_URL, STUDIO } from "@/lib/site"; type Props = { params: Promise<{ slug: string }> }; export function generateStaticParams() { return getAllPosts().map((p) => ({ slug: p.slug })); } export async function generateMetadata({ params }: Props): Promise { const { slug } = await params; const post = getPost(slug); if (!post) return {}; const url = `${SITE_URL}/devblog/${post.slug}`; return { title: post.title, description: post.excerpt, alternates: { canonical: url }, openGraph: { type: "article", title: post.title, description: post.excerpt, url, publishedTime: post.date, authors: post.author ? [post.author] : undefined, tags: post.tags, }, twitter: { card: "summary_large_image", title: post.title, description: post.excerpt, }, }; } const mdxComponents = { // The page title is already the document's h1. A `#` heading inside a post // renders as an h2 so there is never a second one. h1: (props: React.HTMLAttributes) => (

), h2: (props: React.HTMLAttributes) => (

), h3: (props: React.HTMLAttributes) => (

), h4: (props: React.HTMLAttributes) => (

), p: (props: React.HTMLAttributes) => (

), ul: (props: React.HTMLAttributes) => (