道招

怎么让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里面拿到titledescription等信息,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里面实现路由

file

结合官网的解释,我们其实就可以根据动态路由来读取src/markdown目录下对应.md文件内容了

加上前面提到的front-mattermarkedapp/[...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>
  )
}
更新时间:
上一篇:推荐一款运动记录转换工具,支持华为小米运动记录导入高驰佳明RQrun等平台下一篇:nextjs根据动态路由优雅处理目录首页url和无效url

相关文章

markdown是不会用还是不好用?自研vscode插件来帮忙,甲方运营人员大呼好用

背景 随着使用markdown语法编写内容越来越流行,有的程序员也开始给甲方做网站时使用markdown来编写文章了,比如用hexo博客系统建站。 使用markdown语法能减轻程序员寻找富 阅读更多…

nextjs动态生成sitemap.xml的修改日期

nextjs是可以自行生成网站的 sitemap.xml 的,但是在打包发不到生产环境后,发现写的日期并没有生效,而是当时打包时的日期,百思不得其解。 此前是自定义 src/sitemap.js 阅读更多…

nextjs根据动态路由优雅处理目录首页url和无效url

前几天写到 怎么让nextjs根据动态路由读取指定markdown文件内容 ,提到了在nextjs项目的app目录下创建一个[...slug],然后在里面的page.js里面实现路由 func 阅读更多…

nextjs根据动态路由优雅处理目录首页url和无效url

前几天写到 怎么让nextjs根据动态路由读取指定markdown文件内容 ,提到了在nextjs项目的app目录下创建一个[...slug],然后在里面的page.js里面实现路由 func 阅读更多…

关注道招网公众帐号
友情链接
消息推送
道招网关注互联网,分享IT资讯,前沿科技、编程技术,是否允许文章更新后推送通知消息。
允许
不用了