在 Next.js 中自动生成 sitemap.xml
太棒了!您已经为美观且性能卓越的 Next.js 网站创建了所有组件和样式。接下来该做什么呢?
您希望在导出的包的根目录中提供一些关键文件,但 Next.js 默认只支持从/static文件夹复制文件。那么,如何添加例如 `<filename>` 文件sitemap.xml,即使是以自动化且始终保持最新状态的方式呢?
让我来向您展示如何为“yarn export”的 Next.js 项目进行设置。
基本的 sitemap.xml 结构
首先,我们需要了解一下一个基本的网站地图需要包含哪些信息。
一份清单……
- 每个可用页面的网址
- 以及相应的日期,以便搜索引擎机器人知道在哪里可以找到页面以及上次更改的时间。
就是这样!如果您想了解更多信息,可以查看谷歌的“构建和提交站点地图”网站。
收集所需信息
在将文件写入导出的 /out 文件夹之前,我们需要先获取所需的信息:页面 URL 和最后修改日期。
为此,我编写了这个函数,它可以返回 /pages 文件夹内所有文件的路径:
module.exports = () => {
const fileObj = {};
const walkSync = dir => {
// Get all files of the current directory & iterate over them
const files = fs.readdirSync(dir);
files.forEach(file => {
// Construct whole file-path & retrieve file's stats
const filePath = `${dir}${file}`;
const fileStat = fs.statSync(filePath);
if (fileStat.isDirectory()) {
// Recurse one folder deeper
walkSync(`${filePath}/`);
} else {
// Construct this file's pathname excluding the "pages" folder & its extension
const cleanFileName = filePath
.substr(0, filePath.lastIndexOf("."))
.replace("pages/", "");
// Add this file to `fileObj`
fileObj[`/${cleanFileName}`] = {
page: `/${cleanFileName}`,
lastModified: fileStat.mtime
};
}
});
};
// Start recursion to fill `fileObj`
walkSync("pages/");
return fileObj;
};
这将返回一个对象,在我撰写本文时,该对象在我的网站上看起来像这样:
{
"/blog/auto-generate-sitemap-in-next-js": {
"page": "/blog/auto-generate-sitemap-in-next-js",
"lastModified": "2018-10-03T00:25:30.806Z"
},
"/blog/website-and-blog-with-next-js": {
"page": "/blog/website-and-blog-with-next-js",
"lastModified": "2018-10-01T17:04:52.150Z"
},
"/blog": {
"page": "/blog",
"lastModified": "2018-10-03T00:26:02.134Z"
},
"/index": {
"page": "/index",
"lastModified": "2018-10-01T17:04:52.153Z"
}
}
如您所见,我们已经拥有构建网站地图所需的所有信息!
导出时创建文件
在 Next.js 中,创建静态文件包时,通常会运行 `.js` 命令yarn build && yarn export。我们希望在导出之后插入 `.js` 命令,以便在 `/out` 文件夹中创建 `sitemap.xml` 文件。
要接入 package.json 中定义的任何脚本,我们可以添加另一个同名脚本,但以“post”为前缀;
新的 package.json 文件中的 scripts 部分将如下所示:
...
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start",
"export": "next export",
"postexport": "node scripts/postExport.js"
},
...
我选择创建一个名为“scripts”的新文件夹,并在其中创建“postExport.js”文件。现在,每次调用“yarn export”后,该脚本都会运行。
生成 sitemap.xml 内容
此scripts/postExport.js文件将利用我们之前创建的函数来获取所有需要的信息:
const pathsObj = getPathsObject();
然后,我们将创建 sitemap.xml 文件:
const sitemapXml = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${Object.keys(pathsObj).map(
path => `<url>
<loc>https://embiem.me${path}</loc>
<lastmod>${
formatDate(new Date(pathsObj[path].lastModified))
}</lastmod>
</url>`
)}
</urlset>`;
fs.writeFileSync("out/sitemap.xml", sitemapXml);
就这样!嗯,差不多了。我用了 formatDate 函数,把日期转换成了想要的字符串格式。
你可以直接使用 `date` .substr(),因为它已经包含了 ISO 格式的日期,或者使用像date-fnspathsObj[path].lastModified这样的库。我决定从网上复制一个可行的解决方案:
module.exports = function formatDate(date) {
var d = new Date(date),
month = "" + (d.getMonth() + 1),
day = "" + d.getDate(),
year = d.getFullYear();
if (month.length < 2) month = "0" + month;
if (day.length < 2) day = "0" + day;
return [year, month, day].join("-");
};
现在运行yarn export,就会出现一个文件out/sitemap.xml!
挑战!创建 robots.txt 文件
基于此,您现在应该很容易就能创建包含所需内容的 robots.txt 文件。
如果你想知道我是怎么做到的,请查看我网站仓库中的 scripts 文件夹。
如果你有其他解决办法,请告诉我。
后记
这是我在这社区的第一篇帖子👋。以后我会发更多帖子。你可以在我的博客上找到原文。
文章来源:https://dev.to/embiem/auto-generate-sitemapxml-in-nextjs-2nh1