import { format, parseISO } from 'date-fns'; import fs from 'fs'; import matter from 'gray-matter'; import mdxPrism from 'mdx-prism'; import { GetStaticPaths, GetStaticProps } from 'next'; import { serialize } from 'next-mdx-remote/serialize'; import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'; import Head from 'next/head'; import Image from 'next/image'; import Link from 'next/link'; import path from 'path'; import React from 'react'; import rehypeAutolinkHeadings from 'rehype-autolink-headings'; import rehypeSlug from 'rehype-slug'; import Layout, { WEBSITE_HOST_URL } from '../../components/Layout'; import { MetaProps } from '../../types/layout'; import { PostType } from '../../types/post'; import { postFilePaths, POSTS_PATH } from '../../utils/mdxUtils'; // Custom components/renderers to pass to MDX. // Since the MDX files aren't loaded by webpack, they have no knowledge of how // to handle import statements. Instead, you must include components in scope // here. const components = { Head, Image, Link, }; type PostPageProps = { source: MDXRemoteSerializeResult; frontMatter: PostType; }; const PostPage = ({ source, frontMatter }: PostPageProps): JSX.Element => { const customMeta: MetaProps = { title: `${frontMatter.title} - Hunter Chang`, description: frontMatter.description, image: `${WEBSITE_HOST_URL}${frontMatter.image}`, date: frontMatter.date, type: 'article', }; return (

{frontMatter.title}

{format(parseISO(frontMatter.date), 'MMMM dd, yyyy')}

); }; export const getStaticProps: GetStaticProps = async ({ params }) => { const postFilePath = path.join(POSTS_PATH, `${params.slug}.mdx`); const source = fs.readFileSync(postFilePath); const { content, data } = matter(source); const mdxSource = await serialize(content, { // Optionally pass remark/rehype plugins mdxOptions: { remarkPlugins: [require('remark-code-titles')], rehypePlugins: [mdxPrism, rehypeSlug, rehypeAutolinkHeadings], }, scope: data, }); return { props: { source: mdxSource, frontMatter: data, }, }; }; export const getStaticPaths: GetStaticPaths = async () => { const paths = postFilePaths // Remove file extensions for page paths .map((path) => path.replace(/\.mdx?$/, '')) // Map the path into the static paths object required by Next.js .map((slug) => ({ params: { slug } })); return { paths, fallback: false, }; }; export default PostPage;