Sitemap

A sitemap aids discovery, not ranking. Google "ignores <priority> and <changefreq> values" and trusts <lastmod> only when "consistently and verifiably" accurate. Use absolute canonical URLs, at most 50,000 per file (50 MB), and keep the file at the root, because a sitemap covers only its own directory unless submitted in Search Console 1 (Sitemaps and robots.txt). The script escapes & as &amp;.

build-sitemap.mjs: generating sitemap.xml with Node.jsJavaScript
import { writeFileSync } from 'node:fs';
const site = 'https://example.com';
const pages = [
  { path: '/', updated: '2026-09-01' },
  { path: '/product?id=45&lang=en', updated: '2026-07-30' },
];
const esc = (s) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;');
const urls = pages.map((p) => `  <url><loc>${esc(site + p.path)}</loc>`
  + `<lastmod>${p.updated}</lastmod></url>`);
const xml = ['<?xml version="1.0" encoding="UTF-8"?>',
  '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">', ...urls, '</urlset>'];
writeFileSync('sitemap.xml', xml.join('\n') + '\n');
console.log(xml.join('\n'));
Output
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url><loc>https://example.com/</loc><lastmod>2026-09-01</lastmod></url>
  <url><loc>https://example.com/product?id=45&amp;lang=en</loc><lastmod>2026-07-30</lastmod></u
    rl>
</urlset>

Take lastmod from real content changes (a CMS field or git log), never from build time.