A blog - detail

April 16, 2025

准备

  • code

详情页

创建文件

在目录的文件夹下创建一个文件page.tsx在文件夹[slug]中。

获取详情

const SlugPage = async ({ params }: { params: { slug: string[] } }) => { const post = getPostBySlug(params.slug.join('')) return ( ... ) } export async function generateStaticParams(): Promise<{ slug: string[] }[]> { const allPosts = await getAllPosts() return allPosts.map((post) => ({ slug: [post.slug], })) } export default SlugPage

获取组件

const SlugPage = async ({ params }: { params: { slug: string[] } }) => { const post = getPostBySlug(params.slug.join('')) let postComponents: any = {} try { postComponents = await import( '../../../content/blogs/' + params.slug.join('') + '/components.ts' ) } catch (e: any) { if (!e || e.code !== 'MODULE_NOT_FOUND') { throw e } } return ( ... ) }

渲染页面

const SlugPage = async ({ params }: { params: { slug: string[] } }) => { const post = getPostBySlug(params.slug.join('')) let postComponents: any = {} try { postComponents = await import( '../../../content/blogs/' + params.slug.join('') + '/components.ts' ) } catch (e: any) { if (!e || e.code !== 'MODULE_NOT_FOUND') { throw e } } return ( <Mdx content={post.content} postComponents={postComponents} /> ) }

<Mdx />组件

使用next-mdx-remote/rsc渲染 mdx 文件

import { MDXRemote } from 'next-mdx-remote/rsc' export const Mdx = async ({ content = '', postComponents = {}}) => { return ( <MDXRemote source={content} components={components} options={options as any} /> ) }

mdx样式

创建一个样式文件,自定义mdx渲染的样式。

.markdown { line-height: 28px; --path: none; --radius-top: 12px; --radius-bottom: 12px; --padding-top: 1rem; --padding-bottom: 1rem; } .markdown p { @apply pb-8; } .markdown a { @apply border-b-[1px] border-[--link] text-[--link]; } .markdown hr { @apply pt-8 opacity-60 dark:opacity-10; } .markdown h2 { @apply mt-2 pb-8 text-3xl font-bold; } .markdown h3 { @apply mt-2 pb-8 text-2xl font-bold; } .markdown h4 { @apply mt-2 pb-8 text-xl font-bold; } .markdown :not(pre) > code { border-radius: 10px; background: var(--inlineCode-bg); color: var(--inlineCode-text); padding: 0.15em 0.2em 0.05em; white-space: normal; } .markdown pre { @apply -mx-4 mb-8 overflow-y-auto p-4 text-sm; clip-path: var(--path); border-top-right-radius: var(--radius-top); border-top-left-radius: var(--radius-top); border-bottom-right-radius: var(--radius-bottom); border-bottom-left-radius: var(--radius-bottom); padding-top: var(--padding-top); padding-bottom: var(--padding-bottom); } .markdown pre code { width: auto; } .markdown blockquote { @apply relative -left-2 -ml-4 mb-8 pl-4; font-style: italic; border-left: 3px solid hsla(0, 0%, 0%, 0.9); border-left-color: inherit; opacity: 0.8; } .markdown blockquote p { margin: 0; padding: 0; } .markdown p img { margin-bottom: 0; } .markdown ul { margin-top: 0; padding-bottom: 0; padding-left: 0; padding-right: 0; padding-top: 0; margin-bottom: 1.75rem; list-style-position: outside; list-style-image: none; list-style: disc; } .markdown li { margin-bottom: calc(1.75rem / 2); } .markdown img { @apply mb-8; max-width: 100%; } .markdown pre [data-highlighted-line] { margin-left: -16px; padding-left: 12px; border-left: 4px solid #ffa7c4; background-color: #022a4b; display: block; padding-right: 1em; }

TailwindCSS >= 4.0,使用@reference替换@reference

并在<Mdx />组件文件中引入,使样式生效

import '@/styles/mdx.css'

References