道招

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

如果您发现本文排版有问题,可以先点击下面的链接切换至老版进行查看!!!

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

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

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
  };
}

这样的话,在访问 example.com/abc 时读取src/markdown里面的abc.md的内容作为结果来渲染,但是实际运行过程发现了两个改进点。

访问目录url

但是当我们将abc作为目录,也就是说可能还有如下url:/abc/a,/abc/b,分别读取的是src/markdown/abc/a.mdsrc/markdown/abc/b.md,我们更希望访问/abc时读取的是src/markdown/abc/index.md,而不一定是src/markdown/abc.md,毕竟把abc相关的内容都放在abc这个文件夹内更加方便管理,此时我们可以将之前的getFileData进行优化。

访问不存在的url时

访问的url不存在,其实可能认为是在对应的src/markdown文件夹内找不到与url匹配的markdown文件,为了避免出现nextjs渲染失败的情况,我们可以直接写入兜底内容作为结果来渲染。 比如提示直接当前url不存在。

完整代码如下:

export async function getFileData(slug, dir = './') {
  const slugList = Array.isArray(slug) ? slug : [slug];
  // 最后一项为文件名,其余是目录名
  const rawId = slugList.pop() || '';
  let id = rawId || 'index'; // 为空时默认为 index
  let dirPath  = dir;
  if (slugList.length > 0) {
    dirPath += slugList.join('/') + '/';
  }
  // dirPath可能以./开头,需要去掉.
  const pathname = dirPath.replace(/^(\.)/, '') + rawId;
  let file = path.join(absPath(dirPath), `${id}.${fileExt}`);
  let stat = await fsp.stat(file).catch(err => {
    console.log('fsp.stat 1~ ', err + '');
  });
  // 尝试将原id作为目录名,读取其index.md
  if (!stat) {
    dirPath = dirPath + '/' + id;
    id = 'index';
    file = path.join(absPath(dirPath), `${id}.${fileExt}`);
  }
  stat = await fsp.stat(file).catch(err => {
    console.log('fsp.stat 2~ ', err + '');
  });
  // 文件不存在直接返回空对象
  if (!stat) {
    return {
      title: '当前URL不存在',
      html: `<section><p>请确认当前页面的URL是否有误</p><p>记录时间:${new Date()}</p></section>`,
    };
  }

  const data = await fsp.readFile(file, 'utf8');
  const matter = fm(data);
  const html = (await parse(matter.body)).toString();
  // date formatting
  const date = matter.attributes.fakeAsUpdateDaily
    ? new Date()
    : (matter.attributes.date || stat.ctime)
  matter.attributes.date = date.toUTCString();
  matter.attributes.dateYMD = dateformat.ymd(date);
  matter.attributes.dateFriendly = dateformat.friendly(date);
  // word count
  const
    roundTo     = 10,
    readPerMin  = 200,
    numFormat   = new Intl.NumberFormat('en'),
    count       = matter.body.replace(/\W/g, ' ').replace(/\s+/g, ' ').split(' ').length,
    words       = Math.ceil(count / roundTo) * roundTo,
    mins        = Math.ceil(count / readPerMin);
  matter.attributes.wordcount = `${ numFormat.format(words) } words, ${ numFormat.format(mins) }-minute read`;
  return {
    pathname,
    id,
    html,
    ...matter.attributes
  };
}
更新时间:
上一篇:怎么让nextjs根据动态路由读取指定markdown文件内容下一篇:运动记录转换工具怎么支持转换华为的跳绳记录到佳明的

相关文章

怎么让nextjs根据动态路由读取指定markdown文件内容

最近用了用nextjs,发现用它建设个小型站点还是很方便的,兼备服务端渲染。 站点架设好之后,后面更多的是写文章,不需要太多的代码改动了,一般来说写写文章,又不用花哨的排版的话,用markdown就 阅读更多…

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

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

怎么让nextjs根据动态路由读取指定markdown文件内容

最近用了用nextjs,发现用它建设个小型站点还是很方便的,兼备服务端渲染。 站点架设好之后,后面更多的是写文章,不需要太多的代码改动了,一般来说写写文章,又不用花哨的排版的话,用markdown就 阅读更多…

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

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

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