1. Use gatsby-source-filesystem to add the static page files to your filesystem so you can query them.
In gatsby-config.js add the following:
{
resolve: "gatsby-source-filesystem",
options: {
name: "pages",
path: "./src/pages/",
},
},
Note: Whatever you use for the name property here will become what you filter on in the query.
2. Add gatsby-transformer-gitinfo to your project to add some git information on File fields from the latest commit. (plugin docs)
Just declare it underneath step 1 like so:
{
resolve: "gatsby-source-filesystem",
options: {
name: "pages",
path: "./src/pages/",
},
},
`gatsby-transformer-gitinfo`,
We use this plugin because any of the modifiedTime/mtime/changeTime/ctime fields in Gatsby's File nodes are overwritten at deploy time because git does not record or keep file timestamp metadata.
3. Now we have all the necessary data added to GraphQL and can query it to see what it looks like:
query MyQuery {
site {
siteMetadata {
siteUrl
}
}
allSitePage {
nodes {
path
}
}
allFile(filter: {sourceInstanceName: {eq: "pages"}}) {
edges {
node {
fields {
gitLogLatestDate
}
name
}
}
}
}
Note: sourceInstanceName should equal whatever you set for options.name in step 1.
The query result should look something like this:
{
"data": {
"site": {
"siteMetadata": {
"siteUrl": "https://www.example.com"
}
},
"allSitePage": {
"nodes": [
{
"path": "/dev-404-page/"
},
{
"path": "/404/"
},
{
"path": "/404.html"
},
{
"path": "/contact/"
},
{
"path": "/features/"
},
{
"path": "/"
},
{
"path": "/privacy/"
},
{
"path": "/terms/"
}
]
},
"allFile": {
"edges": [
{
"node": {
"fields": {
"gitLogLatestDate": "2021-12-09 23:18:29 -0600"
},
"name": "404"
}
},
{
"node": {
"fields": {
"gitLogLatestDate": "2021-12-09 23:18:29 -0600"
},
"name": "contact"
}
},
{
"node": {
"fields": {
"gitLogLatestDate": "2021-12-09 23:18:29 -0600"
},
"name": "privacy"
}
},
{
"node": {
"fields": {
"gitLogLatestDate": "2021-12-07 19:11:12 -0600"
},
"name": "index"
}
},
{
"node": {
"fields": {
"gitLogLatestDate": "2021-12-09 23:18:29 -0600"
},
"name": "terms"
}
},
{
"node": {
"fields": {
"gitLogLatestDate": "2021-12-09 23:18:29 -0600"
},
"name": "features"
}
}
]
}
},
"extensions": {}
}
4. Now let's put it all together in gatsby-config.js:
{
resolve: "gatsby-source-filesystem",
options: {
name: "pages",
path: "./src/pages/",
},
},
`gatsby-transformer-gitinfo`,
{
resolve: "gatsby-plugin-sitemap",
options: {
query: `{
site {
siteMetadata {
siteUrl
}
}
allSitePage {
nodes {
path
}
}
allFile(filter: {sourceInstanceName: {eq: "pages"}}) {
edges {
node {
fields {
gitLogLatestDate
}
name
}
}
}
}`,
resolvePages: ({
allSitePage: { nodes: sitePages },
allFile: { edges: pageFiles }
}) => {
return sitePages.map(page => {
const pageFile = pageFiles.find(({ node }) => {
const fileName = node.name === 'index' ? '/' : `/${node.name}/`;
return page.path === fileName;
});
return { ...page, ...pageFile?.node?.fields }
})
},
serialize: ({ path, gitLogLatestDate }) => {
return {
url: path,
lastmod: gitLogLatestDate
}
},
createLinkInHead: true,
},
}
Explanation of the gatsby-plugin-sitemap options:
5. Finally, run gatsby build and you should see the result show up in public/sitemap/sitemap-0.xml
(Seems like gatsby-plugin-sitemap recently switched to this location, so could be elsewhere if you're using an older version of the plugin.)
Result should look like this:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<url>
<loc>https://www.example.com/contact/</loc>
<lastmod>2021-12-10T05:18:29.000Z</lastmod>
</url>
<url>
<loc>https://www.example.com/features/</loc>
<lastmod>2021-12-10T05:18:29.000Z</lastmod>
</url>
<url>
<loc>https://www.example.com/</loc>
<lastmod>2021-12-08T01:11:12.000Z</lastmod>
</url>
<url>
<loc>https://www.example.com/privacy/</loc>
<lastmod>2021-12-10T05:18:29.000Z</lastmod>
</url>
<url>
<loc>https://www.example.com/terms/</loc>
<lastmod>2021-12-10T05:18:29.000Z</lastmod>
</url>
</urlset>
Extra, possibly helpful details - versions of everything I'm using:
"gatsby": "^4.0.0",
"gatsby-plugin-sitemap": "^5.3.0",
"gatsby-source-filesystem": "^4.3.0",
"gatsby-transformer-gitinfo": "^1.1.0",