typescript - 使用 Next.js 13 + 应用路由的简单博客 — MDX 或其他
我正在将一个 Gatsby 网站迁移到 Next.js(v13.4),并使用新的 App Router。但是我在迁移博客时有些困惑,并且由于 App Router 是新的,我在网上很难找到仍然准确的指导。
在 Gatsby 上,可以创建一堆带有 frontmatter 的 MDX 文件,然后使用动态 slug 将它们渲染到页面上。对于博客索引,只需创建一个页面并对 frontmatter 进行 GraphQL 查询。很简单,只是我觉得 GraphQL 在仅仅访问文件系统时显得有些笨重,这也是我迁移的部分原因。
这就是我卡住的地方。
索引页
在 Next.js 上,似乎实现这个的方法是使用常规的 Node fs 和 path 模块来遍历 MDX 文件。Next 有一个标准的元数据格式,我想我可以用它来获取元数据?或者我可以定义自己的 TypeScript 类型。但我不确定在遍历时用基于 Next 的方式解析它是什么样的。
另一种方法是使用标准的 Markdown 前置元数据以及 gray-matter……我现在已经让它工作了,但似乎是一个不必要的依赖。
个人博客页面
这是我卡住的地方。Next 的官方文档展示了如何在页面中导入一个 MDX 文件,但由于我需要一个动态的 slug,导入方法行不通。我认为我需要做的是从文件系统读取它,然后解析它。gray-matter可以将 frontmatter 从 MDX 中分离出来,但实际上并不会解析 MDX。
很多示例使用了 Next 的远程 MDX 功能,但鉴于这些文件是本地的,这显得很愚蠢。
我的怀疑是我可能需要完全放弃 Next 的 MDX 包,而使用某个第三方的;但我不确定那里的最佳实践是什么,而且,很多现有的教程仍然假设使用的是 Pages Router。
我可以完全放弃 MDX,这样管理文章会有点尴尬,但似乎还是可行的。我想要做到这一点,我得放弃动态 slug,为每篇文章创建自己独立的基于 slug 的目录中的 page.tsx 文件。我觉得这样也没问题,因为我可以在一个 layout 文件中集中处理共享的内容。
但随后我又卡在了索引文件上:去掉那些元数据以渲染索引的合适方法是什么?我能想到的最好的方法是把它移到自己的文件,比如 meta.json,然后由帖子级别的 page.tsx 和索引文件共同读取,但我并不喜欢这种做法。
无论如何。这很多。我只想建立一个简单、低流量的博客,能够轻松编辑,集中管理布局信息,并自动生成索引页面。但我搞不清楚在 Next.js 13 + App Router 中应该怎么做。能帮我吗?
答案#1
根据你的需求,我认为选择 gray-matter 和 react-markdown 会是最好的。如果你不需要动态 slug,那么只需要添加 mdx 依赖,并在合适的文件结构中使用 page.mdx 就可以让它工作。如果你需要动态页面,gray-matter 和 react-markdown 是更好的选择。
//[slug]/page.tsx
async getContent(slug){...} // can use gray matter to separate meta and content
export const metadata = {...} // from getMetadata - can be from the .md file
export default sync function BlogPage({params: {slug}}) {
const {data, content} = await getContent(slug);
...
return (
<...some-code>
<ReactMarkdown content={content} {...extra plugins}/>
</...>
)
}
