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'
}
});
};
- 分类:
- Web前端
相关文章
怎么让nextjs根据动态路由读取指定markdown文件内容
最近用了用nextjs,发现用它建设个小型站点还是很方便的,兼备服务端渲染。 站点架设好之后,后面更多的是写文章,不需要太多的代码改动了,一般来说写写文章,又不用花哨的排版的话,用markdown就 阅读更多…
nextjs根据动态路由优雅处理目录首页url和无效url
前几天写到 怎么让nextjs根据动态路由读取指定markdown文件内容 ,提到了在nextjs项目的app目录下创建一个[...slug],然后在里面的page.js里面实现路由 func 阅读更多…