import { removeLeadingSlash } from 'vuepress/shared'; import { logger } from './logger.js'; const reportedLocales = []; const stripLocalePrefix = ({ path, pathLocale }) => path.replace(pathLocale, '/'); /** * @returns A map with keys of rootPath and string[] value for pathLocales */ const getPagesLocaleMap = (app) => app.pages.reduce((map, page) => { const rootPath = stripLocalePrefix(page); const pathLocales = map.get(rootPath) || []; pathLocales.push(page.pathLocale); return map.set(rootPath, pathLocales); }, new Map()); export const getSitemapInfos = (app, options) => { const { changefreq = 'daily', excludePaths = ['/404.html'], modifyTimeGetter = (page) => page.data.git?.updatedTime ? new Date(page.data.git.updatedTime).toISOString() : '', } = options; const { base, locales } = app.options; const pageLocalesMap = getPagesLocaleMap(app); const sitemapInfos = []; app.pages.forEach((page) => { const pageOptions = page.frontmatter.sitemap; if (pageOptions === false) return; const metaRobotTags = (page.frontmatter.head ?? []).find((head) => head[1].name === 'robots'); if ( // meta tags do not allow index (metaRobotTags?.[1].content || '') .split(/,/u) .map((content) => content.trim()) .includes('noindex') || // exclude in plugin options excludePaths.includes(page.path)) return; const lastModifyTime = modifyTimeGetter(page, app); const rootPath = stripLocalePrefix(page); const relatedLocales = pageLocalesMap.get(rootPath); let links = []; if (relatedLocales.length > 1) { // warnings for missing `locale[path].lang` in debug mode if (app.env.isDebug) relatedLocales.forEach((localePrefix) => { if (!locales[localePrefix].lang && !reportedLocales.includes(localePrefix)) { logger.warn(`"lang" option for ${localePrefix} is missing`); reportedLocales.push(localePrefix); } }); links = relatedLocales.map((localePrefix) => ({ lang: locales[localePrefix]?.lang || 'en', url: `${base}${removeLeadingSlash(localePrefix)}${rootPath.substring(1)}`, })); } const sitemapInfo = { ...(changefreq ? { changefreq } : {}), links, ...(lastModifyTime ? { lastmod: lastModifyTime } : {}), ...pageOptions, }; // log sitemap info in debug mode if (app.env.isDebug) logger.info(`sitemap option for ${page.path}: ${JSON.stringify(sitemapInfo, null, 2)}`); sitemapInfos.push([page.path, sitemapInfo]); }); return sitemapInfos; };