1

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

 6 months ago
source link: https://www.daozhao.com/11088.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK