Instantly share code, notes, and snippets.

Embed
What would you like to do?
35 lines to build a sitemap for next.js projects
#! /usr/bin/env node
// I am ./bin/buildSitemap.js
const path = require('path')
const glob = require('glob')
const fs = require('fs')
const SITE_ROOT = process.env.SITE_ROOT || 'https://www.actionherojs.com'
const SOURCE = process.env.SOURCE || path.join(__dirname, '..', 'pages', '/**/*.js')
const DESTINATION = process.env.DESTINATION || path.join(__dirname, '..', 'static', 'sitemap.xml')
let diskPages = glob.sync(SOURCE)
let xml = ''
xml += '<?xml version="1.0" encoding="UTF-8"?>'
xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
diskPages.forEach((page) => {
let stats = fs.statSync(page)
let modDate = new Date(stats.mtime)
let lastMod = `${modDate.getFullYear()}-${('0' + (modDate.getMonth() + 1)).slice(-2)}-${('0' + modDate.getDate()).slice(-2)}`
page = page.replace(path.join(__dirname, '..', 'pages'), '')
page = page.replace(/.js$/, '')
page = `${SITE_ROOT}${page}`
if (page.match(/.*\/index$/)) {
page = page.replace(/(.*)index$/, '$1')
}
xml += '<url>'
xml += `<loc>${page}</loc>`
xml += `<lastmod>${lastMod}</lastmod>`
xml += `<changefreq>always</changefreq>`
xml += `<priority>0.5</priority>`
xml += '</url>'
})
xml += '</urlset>'
fs.writeFileSync(DESTINATION, xml)
console.log(`Wrote sitemap for ${diskPages.length} pages to ${DESTINATION}`)
@416serg

This comment has been minimized.

Show comment
Hide comment
@416serg

416serg Dec 15, 2017

Hey @evantahler, this is great. How would I add this to the configuration and is it possible to use this with pages that get generated dynamically via an API call - so for example, at request for /, I run a fetch to build out all the pages for /job/001, /job/002, etc. These get updated on a regular basis so I would want the sitemap to update whenever the request comes through I guess, without impacting the performance of the application

416serg commented Dec 15, 2017

Hey @evantahler, this is great. How would I add this to the configuration and is it possible to use this with pages that get generated dynamically via an API call - so for example, at request for /, I run a fetch to build out all the pages for /job/001, /job/002, etc. These get updated on a regular basis so I would want the sitemap to update whenever the request comes through I guess, without impacting the performance of the application

@designspin

This comment has been minimized.

Show comment
Hide comment
@designspin

designspin Feb 19, 2018

@416serg, I managed to implement a sitemap using something similar to this. Rather than implementing all pages with the same content as above I preg_matched pages and ran a function to give me the output for a specific page type. My content was coming from an API, so I set all those functions up as async, collected them in an array and ran a Promise.all to get the final output.

designspin commented Feb 19, 2018

@416serg, I managed to implement a sitemap using something similar to this. Rather than implementing all pages with the same content as above I preg_matched pages and ran a function to give me the output for a specific page type. My content was coming from an API, so I set all those functions up as async, collected them in an array and ran a Promise.all to get the final output.

@nathanqueija

This comment has been minimized.

Show comment
Hide comment
@nathanqueija

nathanqueija Mar 29, 2018

@designspin can you, please, provide an example? Thanks!

nathanqueija commented Mar 29, 2018

@designspin can you, please, provide an example? Thanks!

@danakt

This comment has been minimized.

Show comment
Hide comment
@danakt

danakt Apr 3, 2018

You don't have to handle _document.js in the pages folder. I think that you need to add a condition to the code.

danakt commented Apr 3, 2018

You don't have to handle _document.js in the pages folder. I think that you need to add a condition to the code.

@baires

This comment has been minimized.

Show comment
Hide comment
@baires

baires May 22, 2018

You can just exclude _documents.js by fine tuning the glob pattern:

const SOURCE = process.env.SOURCE || path.join(__dirname, '..', 'pages', '/**/!(_*).js');

baires commented May 22, 2018

You can just exclude _documents.js by fine tuning the glob pattern:

const SOURCE = process.env.SOURCE || path.join(__dirname, '..', 'pages', '/**/!(_*).js');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment