道招

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

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

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

nextjs是可以自行生成网站的sitemap.xml的,但是在打包发不到生产环境后,发现写的日期并没有生效,而是当时打包时的日期,百思不得其解。

此前是自定义src/sitemap.js来实现的。

import siteConfig from '@/app/siteConfig';
import { getMdList, getUpdateData } from '@/lib/utils';

export default function sitemap() {
  const mdList = getMdList();
  const pathnameList = mdList.map(item => item.pathname);

  const updateDate = new Date();

  const pageList = pathnameList.map(item => {
    // 如果是 /xxx/index, 则去掉 /index
    const pathname = item.replace(/\/index$/, '');
    return {
      url: siteConfig.siteUrl + pathname,
      lastModified: updateDate,
      changeFrequency: 'daily',
      priority: 0.5,
    }
  }).filter(item => item.url !== siteConfig.siteUrl); // 过滤掉首页

  return [
    {
      url: siteConfig.siteUrl,
      lastModified: updateDate,
      changeFrequency: 'daily',
      priority: 1,
    },
    ...pageList,
  ]
}

自己期望的是每次打开sitemap.xml时,里面的lastmod就是用户打开时的时间之类的,结果并非如此。

最后自己尝试了改用读取文件(该文件内写入最新的时间)

const updateDate = getUpdateData();

function getUpdateData() {
  const filePath = path.join(process.cwd(), './src/updateDate.js');
  const isFileExists = fs.existsSync(filePath);
  const ts = new Date();
  if (!isFileExists) {
    return ts;
  } else {
    return fs.readFileSync(filePath, 'utf-8') || ts;
  }
}

同时在定时任务中加入

4 4 * * * sh /home/schedule_work.sh > /home/project/src/updateDate.js

发现也是徒劳的,获取到的时间依然是打包时的时间,但是项目没新内容更新的话,总不能动不动就重新打包一次吧

经过研究官网发现有个dynamic 传送门

Change the dynamic behavior of a layout or page to fully static or fully dynamic.

Good to know: The new model in the app directory favors granular caching control at the fetch request level over the binary all-or-nothing model of getServerSideProps and getStaticProps at the page-level in the pages directory. The dynamic option is a way to opt back in to the previous model as a convenience and provides a simpler migration path.

export const dynamic = 'force-dynamic';

把直接的sitemap.js的逻辑迁移到src/app/sitemap.xml/route.js,让该url返回xml格式的内容即可实现跟之前的src/app/sitemap.js一样效果啦。

完整代码如下

import { NextResponse } from "next/server";
import siteConfig from '@/app/siteConfig';
import { getMdList, getUpdateData } from '@/lib/utils';

function getUrlList() {
  const mdList = getMdList();
  const pathnameList = mdList.map(item => item.pathname);

  const updateDate = (getUpdateData() + '').trim();

  const pageList = pathnameList.map(item => {
    // 如果是 /xxx/index, 则去掉 /index
    const pathname = item.replace(/\/index$/, '');
    return {
      url: siteConfig.siteUrl + pathname,
      lastModified: updateDate,
      changeFrequency: 'daily',
      priority: 0.5,
    }
  }).filter(item => item.url !== siteConfig.siteUrl); // 过滤掉首页

  return [
    {
      url: siteConfig.siteUrl,
      lastModified: updateDate,
      changeFrequency: 'daily',
      priority: 1,
    },
    ...pageList,
  ]
}

function createSitemapUrlSet () {
  const list = getUrlList();
  const urlSet = list.map((item) => (
    `<url>
        <loc>${item.url}</loc>
        <lastmod>${item.lastModified}</lastmod>
        <changefreq>${item.changeFrequency}</changefreq>
        <priority>${item.priority}</priority>
      </url>`
  )).join('');

  return (
    `<urlset 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" 
      xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
      xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
        ${urlSet}
      </urlset>`
  );
};
export const dynamic = 'force-dynamic' // defaults to force-static

export async function GET(request) {
  const xmlStr = createSitemapUrlSet();

  return new NextResponse(xmlStr, {
    headers: {
      'Content-Type': 'text/xml'
    }
  });
};
更新时间:
上一篇:eletron应用、electron npm包和前端静态资源怎么通信下一篇:【转载】Keep运动记录可以转换成fit和tcx格式导入高驰佳明啦

相关文章

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

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

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

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

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