返回 marp
[slug].tsx
根目录 / website / pages / blog / [slug].tsx
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
71 lines Plain Text