怎么让nextjs根据动态路由读取指定markdown文件内容
怎么让nextjs根据动态路由读取指定markdown文件内容
最近用了用nextjs,发现用它建设个小型站点还是很方便的,兼备服务端渲染。 站点架设好之后,后面更多的是写文章,不需要太多的代码改动了,一般来说写写文章,又不用花哨的排版的话,用markdown就很方便了。
使用的是nextjs最新14.x版本+app router模式,
front-matter
为了能让markdown文件如果文章内容部分外,还兼有标题、发布时间、关键词等自定义信息,我们可以借助front-matter
--- title: 测试 description: '测试下描述' keywords: '关键词' date: 2023-12-16 --- 这里就是内容啦
这里的
title
等信息就可以在front-matter的帮助下,能程序能直接识别出来了,比如就可以将里面的title内容放在html的title里面了。
front-matter用法如下
import { promises as fsp } from 'fs';
import fm from 'front-matter';
const data = await fsp.readFile('abc.md', 'utf8');
const matter = fm(data);
然后我们就能在matter
里面拿到title
、description
等信息,md文件的主体内容则在matter.body
里面
marked
有时我们在markdown里面可能会写些html,并且有些排版只能依靠html来完成了
import { parse } from 'marked';
const data = await fsp.readFile('abc.md', 'utf8');
const matter = fm(data);
const html = (await parse(matter.body)).toString();
nextjs根据url读取对应的markdown文件
我们创建一个app目录下创建一个[...slug]
,然后在里面的page.js
里面实现路由
结合官网的解释,我们其实就可以根据动态路由来读取src/markdown目录下对应.md
文件内容了
加上前面提到的front-matter
和marked
,app/[...slug]/page.js的完整代码如下
import { promises as fsp } from 'fs';
import path from 'path';
import fm from 'front-matter';
import { parse } from 'marked';
function absPath(dir) {
return (
path.isAbsolute(dir) ? dir : path.join(process.cwd(), './src/markdown', dir)
);
}
async function getFileData(slug, dir = './') {
const slugList = Array.isArray(slug) ? slug : [slug];
// 最后一项为文件名,其余是目录名
const rawId = slugList.pop() || '';
const id = rawId || 'index'; // 为空时默认为 index
let dirPath = dir;
if (slugList.length > 0) {
dirPath += slugList.join('/') + '/';
}
// dirPath可能以./开头,需要去掉.
const pathname = dirPath.replace(/^(\.)/, '') + rawId;
const file = path.join(absPath(dirPath), `${id}.md`);
const stat = await fsp.stat(file).catch(err => {
console.log('file not found ~ ', slugList, err + '');
});
// 文件不存在直接返回空
if (!stat) {
return;
}
const data = await fsp.readFile(file, 'utf8');
const matter = fm(data);
const html = (await parse(matter.body)).toString();
return {
pathname,
id,
html,
...matter.attributes
};
}
export default async function SlugPage({ params }) {
const data = await getFileData(params.slug);
if (!data) {
return (<div>404</div>);
}
return (
<div>
<div className="app-article">
<div className="app-article-title">
<h1>{data.title}</h1>
</div>
<section className="app-article-content" dangerouslySetInnerHTML={{
__html: data.html
}}></section>
</div>
</div>
)
}
- 分类:
- Web前端
相关文章
markdown是不会用还是不好用?自研vscode插件来帮忙,甲方运营人员大呼好用
背景 随着使用markdown语法编写内容越来越流行,有的程序员也开始给甲方做网站时使用markdown来编写文章了,比如用hexo博客系统建站。 使用markdown语法能减轻程序员寻找富 阅读更多…
nextjs根据动态路由优雅处理目录首页url和无效url
前几天写到 怎么让nextjs根据动态路由读取指定markdown文件内容 ,提到了在nextjs项目的app目录下创建一个[...slug],然后在里面的page.js里面实现路由 func 阅读更多…
markdown+NextJS搭建个人博客
如果你平时不喜欢在排版上花时间,不在乎花里胡哨的样式,觉得markdown编辑文件效果就够用?你还想基于markdown搭建一个博客?那NextJS就可以满足你的需求了 NextJS可以使用Reac 阅读更多…
markdown+NextJS搭建个人博客
如果你平时不喜欢在排版上花时间,不在乎花里胡哨的样式,觉得markdown编辑文件效果就够用?你还想基于markdown搭建一个博客?那NextJS就可以满足你的需求了 NextJS可以使用Reac 阅读更多…
nextjs动态生成sitemap.xml的修改日期
nextjs是可以自行生成网站的 sitemap.xml 的,但是在打包发不到生产环境后,发现写的日期并没有生效,而是当时打包时的日期,百思不得其解。 此前是自定义 src/sitemap.js 阅读更多…
nextjs根据动态路由优雅处理目录首页url和无效url
前几天写到 怎么让nextjs根据动态路由读取指定markdown文件内容 ,提到了在nextjs项目的app目录下创建一个[...slug],然后在里面的page.js里面实现路由 func 阅读更多…