| 1 | import { basename } from 'path' |
| 2 | import { |
| 3 | GetStaticPaths, |
| 4 | GetStaticPropsContext, |
| 5 | InferGetStaticPropsType, |
| 6 | } from 'next' |
| 7 | import Link from 'next/link' |
| 8 | import { Layout } from 'components/Layout' |
| 9 | import { Title } from 'components/Title' |
| 10 | import { Typography } from 'components/Typography' |
| 11 | import { BlogHeader } from 'components/blog/BlogHeader' |
| 12 | import { parse, renderToReact } from 'utils/markdown' |
| 13 | |
| 14 | export const getStaticPaths: GetStaticPaths = async () => ({ |
| 15 | paths: require |
| 16 | .context('blog', false, /\.md$/) |
| 17 | .keys() |
| 18 | .map((id) => `/blog/${basename(id, '.md')}`), |
| 19 | fallback: false, |
| 20 | }) |
| 21 | |
| 22 | export const getStaticProps = async ({ params }: GetStaticPropsContext) => { |
| 23 | const slug = params?.slug as string |
| 24 | const { default: md } = await import(`blog/${slug}.md`) |
| 25 | const parsed = await parse(md) |
| 26 | |
| 27 | return { |
| 28 | props: { markdown: { data: parsed.data, mdast: parsed.mdast }, slug }, |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | const Blog = ({ |
| 33 | markdown: { data, mdast }, |
| 34 | slug, |
| 35 | }: InferGetStaticPropsType<typeof getStaticProps>) => ( |
| 36 | <Layout |
| 37 | activeItem="blog" |
| 38 | description={data.description || ''} |
| 39 | image={data.image} |
| 40 | noIndex={!data.date} |
| 41 | title={[data.title || slug, 'Blog']} |
| 42 | > |
| 43 | <Title> |
| 44 | <Link href="/blog">Blog</Link> |
| 45 | </Title> |
| 46 | <div className="container mx-auto px-6 py-12"> |
| 47 | <BlogHeader |
| 48 | title={data.title} |
| 49 | date={data.date ? new Date(data.date) : undefined} |
| 50 | author={data.author} |
| 51 | github={data.github} |
| 52 | slug={slug} |
| 53 | /> |
| 54 | <article className="mx-auto mt-8 max-w-screen-lg"> |
| 55 | {data.image && ( |
| 56 | <figure className="my-12"> |
| 57 | <img |
| 58 | src={data.image} |
| 59 | alt={data.title} |
| 60 | className="mx-auto block w-full max-w-screen-md bg-white shadow-xl" |
| 61 | /> |
| 62 | </figure> |
| 63 | )} |
| 64 | <Typography>{renderToReact(mdast)}</Typography> |
| 65 | </article> |
| 66 | </div> |
| 67 | </Layout> |
| 68 | ) |
| 69 | |
| 70 | export default Blog |
| 71 |