import 'css/prism.css'; import 'katex/dist/katex.css'; import PageTitle from '@/components/PageTitle'; import { components } from '@/components/MDXComponents'; import { MDXLayoutRenderer } from 'pliny/mdx-components'; import { sortPosts, coreContent } from 'pliny/utils/contentlayer'; import { allBlogs, allAuthors } from 'contentlayer/generated'; import type { Authors, Blog } from 'contentlayer/generated'; import PostSimple from '@/layouts/PostSimple'; import PostLayout from '@/layouts/PostLayout'; import PostBanner from '@/layouts/PostBanner'; import { Metadata } from 'next'; import siteMetadata from '@/data/siteMetadata'; const isProduction = process.env.NODE_ENV === 'production'; const defaultLayout = 'PostLayout'; const layouts = { PostSimple, PostLayout, PostBanner, }; export async function generateMetadata({ params, }: { params: { slug: string[] }; }): Promise { const slug = decodeURI(params.slug.join('/')); const post = allBlogs.find((p) => p.slug === slug); const authorList = post?.authors || ['default']; const authorDetails = authorList.map((author) => { const authorResults = allAuthors.find((p) => p.slug === author); return coreContent(authorResults as Authors); }); if (!post) { return; } const publishedAt = new Date(post.date).toISOString(); const modifiedAt = new Date(post.lastmod || post.date).toISOString(); const authors = authorDetails.map((author) => author.name); let imageList = [siteMetadata.socialBanner]; if (post.images) { imageList = typeof post.images === 'string' ? [post.images] : post.images; } const ogImages = imageList.map((img) => { return { url: img.includes('http') ? img : siteMetadata.siteUrl + img, }; }); return { title: post.title, description: post.summary, openGraph: { title: post.title, description: post.summary, siteName: siteMetadata.title, locale: 'en_US', type: 'article', publishedTime: publishedAt, modifiedTime: modifiedAt, url: './', images: ogImages, authors: authors.length > 0 ? authors : [siteMetadata.author], }, twitter: { card: 'summary_large_image', title: post.title, description: post.summary, images: imageList, }, }; } export const generateStaticParams = async () => { const paths = allBlogs.map((p) => ({ slug: p.slug.split('/') })); return paths; }; export default async function Page({ params }: { params: { slug: string[] } }) { const slug = decodeURI(params.slug.join('/')); const sortedPosts = sortPosts(allBlogs) as Blog[]; const postIndex = sortedPosts.findIndex((p) => p.slug === slug); const prev = coreContent(sortedPosts[postIndex + 1]); const next = coreContent(sortedPosts[postIndex - 1]); const post = sortedPosts.find((p) => p.slug === slug) as Blog; const authorList = post?.authors || ['default']; const authorDetails = authorList.map((author) => { const authorResults = allAuthors.find((p) => p.slug === author); return coreContent(authorResults as Authors); }); const mainContent = coreContent(post); const jsonLd = post.structuredData; jsonLd['author'] = authorDetails.map((author) => { return { '@type': 'Person', name: author.name, }; }); const Layout = layouts[post.layout || defaultLayout]; return ( <> {isProduction && post && 'draft' in post && post.draft === true ? (
Under Construction{' '} 🚧
) : ( <>