import { notFound } from 'next/navigation' import { MDXRemote } from 'next-mdx-remote/rsc' import { getMDXComponents } from '@/mdx-components' import remarkMath from 'remark-math' import remarkGfm from 'remark-gfm' import smartypants from 'remark-smartypants' import rehypePrettyCode from 'rehype-pretty-code' import { transformerCopyButton } from '@rehype-pretty/transformers' import rehypeAutolinkHeadings from 'rehype-autolink-headings' import rehypeKatex from 'rehype-katex' import rehypeSlug from 'rehype-slug' import rehypeExternalLinks from 'rehype-external-links' import type { Element } from 'hast' import type { LineElement } from 'rehype-pretty-code' import { getPosts, getPost } from '@/lib/posts' import { TableOfContents } from '@/components/blog/TableOfContents' import { ScrollToTop } from '@/components/ui/ScrollToTop' import { ReadingProgress } from '@/components/ui/ReadingProgress' export async function generateStaticParams() { const posts = await getPosts() if (posts.length === 0) { return [{ slug: '__placeholder__' }] } return posts.map((post) => ({ slug: post.slug })) } export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }) { const slug = (await params).slug const post = await getPost(slug) if (!post) return { title: 'Not Found' } return { title: `${post.title} | blog` } } export default async function PostPage({ params }: { params: Promise<{ slug: string }> }) { const slug = (await params).slug const post = await getPost(slug) if (!post) notFound() return ( <>

{post.title}

{post.author && by {post.author}} {post.readingTime} min read
{post.coverImage && ( Cover image )} {post.tags.length > 0 && (
{post.tags.map((tag) => ( {tag} ))}
)}
(metaString || '') + ' showLineNumbers', grid: true, onVisitLine(node: LineElement) { if (node.children.length === 0) { node.children = [{ type: 'text', value: ' ' }]; } }, onVisitTitle(element: Element) { const existingClassNames = Array.isArray(element.properties.className) ? element.properties.className : []; element.properties.className = [ ...existingClassNames, 'vscode-title', ]; element.children = [ { type: 'element', tagName: 'span', properties: { className: ['vscode-dots'] }, children: [ { type: 'element', tagName: 'span', properties: { className: ['dot-red'] }, children: [] }, { type: 'element', tagName: 'span', properties: { className: ['dot-yellow'] }, children: [] }, { type: 'element', tagName: 'span', properties: { className: ['dot-green'] }, children: [] }, ], }, element.children[0], ]; }, transformers: [ transformerCopyButton({ visibility: 'hover', feedbackDuration: 2_500, }), ], }], rehypeKatex, ], }, }} />
) }