UNPKG

nuxt-simple-sitemap

Version:

Powerfully flexible XML Sitemaps that integrate seamlessly, for Nuxt.

88 lines (87 loc) 3.4 kB
import { defu } from "defu"; import { appendHeader } from "h3"; import { normaliseDate, normaliseSitemapUrls } from "../urlset/normalise.mjs"; import { globalSitemapSources, resolveSitemapSources } from "../urlset/sources.mjs"; import { applyI18nEnhancements } from "../urlset/i18n.mjs"; import { filterSitemapUrls } from "../urlset/filter.mjs"; import { sortSitemapUrls } from "../urlset/sort.mjs"; import { useSimpleSitemapRuntimeConfig } from "../../utils.mjs"; import { escapeValueForXml, wrapSitemapXml } from "./xml.mjs"; export async function buildSitemapIndex(resolvers) { const { sitemaps, // enhancing autoLastmod, // chunking defaultSitemapsChunkSize, autoI18n, isI18nMapped, sortEntries, // xls version, xsl, credits } = useSimpleSitemapRuntimeConfig(); if (!sitemaps) throw new Error("Attempting to build a sitemap index without required `sitemaps` configuration."); function maybeSort(urls) { return sortEntries ? sortSitemapUrls(urls) : urls; } const isChunking = typeof sitemaps.chunks !== "undefined"; const chunks = {}; if (isChunking) { const sitemap = sitemaps.chunks; const sources = await resolveSitemapSources(await globalSitemapSources()); const normalisedUrls = normaliseSitemapUrls(sources.map((e) => e.urls).flat(), resolvers); let enhancedUrls = normalisedUrls.map((e) => defu(e, sitemap.defaults)); if (autoI18n?.locales) enhancedUrls = applyI18nEnhancements(enhancedUrls, { isI18nMapped, autoI18n, sitemapName: sitemap.sitemapName }); const filteredUrls = filterSitemapUrls(enhancedUrls, { ...sitemap, autoI18n, isMultiSitemap: true }); const sortedUrls = maybeSort(filteredUrls); sortedUrls.forEach((url, i) => { const chunkIndex = Math.floor(i / defaultSitemapsChunkSize); chunks[chunkIndex] = chunks[chunkIndex] || { urls: [] }; chunks[chunkIndex].urls.push(url); }); } else { for (const sitemap in sitemaps) { if (sitemap !== "index") { chunks[sitemap] = chunks[sitemap] || { urls: [] }; } } } if (import.meta.prerender) { appendHeader( resolvers.event, "x-nitro-prerender", Object.keys(chunks).map((name) => encodeURIComponent(`/${name}-sitemap.xml`)).join(", ") ); } const entries = []; for (const name in chunks) { const sitemap = chunks[name]; const entry = { sitemap: resolvers.canonicalUrlResolver(`${name}-sitemap.xml`) }; let lastmod = sitemap.urls.filter((a) => !!a?.lastmod).map((a) => typeof a.lastmod === "string" ? new Date(a.lastmod) : a.lastmod).sort((a, b) => (b?.getTime() || 0) - (a?.getTime() || 0))?.[0]; if (!lastmod && autoLastmod) lastmod = /* @__PURE__ */ new Date(); if (lastmod) entry.lastmod = normaliseDate(lastmod); entries.push(entry); } if (sitemaps.index) entries.push(...sitemaps.index.sitemaps); const sitemapXml = entries.map((e) => [ " <sitemap>", ` <loc>${escapeValueForXml(e.sitemap)}</loc>`, // lastmod is optional e.lastmod ? ` <lastmod>${escapeValueForXml(e.lastmod)}</lastmod>` : false, " </sitemap>" ].filter(Boolean).join("\n")).join("\n"); return wrapSitemapXml([ '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">', sitemapXml, "</sitemapindex>" ], resolvers, { version, xsl, credits }); }