astro/packages/integrations/sitemap/src/index.ts

65 lines
2.2 KiB
TypeScript
Raw Normal View History

import fs from 'node:fs';
import type { AstroConfig, AstroIntegration } from 'astro';
const STATUS_CODE_PAGE_REGEXP = /\/[0-9]{3}\/?$/;
Migrate to new config (#2962) * wip: config migration * fix: formatting * refactor: projectRoot -> root * refactor: pageUrlFormat -> format * refactor: buildOptions.site -> site * refactor: public -> publicDir * refactor: dist -> outDir * refactor: styleOptions -> style * fix: some dist tests -> outDir * refactor: remove legacyBuild (with TODOs) * refactor: more legacyBuild cleanup * refactor: server host and port * fix: remove experimentalStaticBuild CLI flag * refactor: src -> srcDir * refactor: devOptions.trailing -> trailing * refactor: remove sitemap + related flags * refactor: experimentalSSR -> experimental.ssr * fix: last devOptions * refactor: drafts -> markdown.drafts * fix: TS error on port as const * refactor: remove pages * refactor: more --project-root updates * refactor: markdownOptions -> markdown * fix: remaining type errors * feat: update AstroUserConfig * refactor: update CLI flag mapper + server mapper * fix: loadFixture projectRoot * fix: merge CLI flags before validating / transforming * wip: attempt to fix bad createRouteManifest config * refactor: combine config.base and config.site * fix: skip route manifest test for now * fix: site and base handling * refactor: update failing config testes * fix: build failure * feat: update config types with migration help * chore: update types * fix(deno): update deno fixture * chore: remove config migration logic * chore: remove logLevel * chore: clean-up config types * chore: update config warning * chore: add changeset * Sitemap Integration (#2965) * feat: add sitemap filter config option * feat: add canonicalURL sitemap config option * docs: update sitemap README * fix: update for new config * fix: filter not being applied * chore: changeset Co-authored-by: bholmesdev <hey@bholmes.dev> * fred pass * fix: Astro.resolve typo * fix: public => publicDir Co-authored-by: bholmesdev <hey@bholmes.dev> Co-authored-by: Fred K. Schott <fkschott@gmail.com>
2022-04-02 18:29:59 +00:00
type SitemapOptions =
| {
/**
* All pages are included in your sitemap by default.
* With this config option, you can filter included pages by URL.
*
* The `page` function parameter is the full URL of your rendered page, including your `site` domain.
* Return `true` to include a page in your sitemap, and `false` to remove it.
*
* ```js
* filter: (page) => page !== 'http://example.com/secret-page'
* ```
*/
filter?(page: string): string;
/**
* If present, we use the `site` config option as the base for all sitemap URLs
* Use `canonicalURL` to override this
*/
canonicalURL?: string;
}
| undefined;
/** Construct sitemap.xml given a set of URLs */
function generateSitemap(pages: string[]) {
// TODO: find way to respect <link rel="canonical"> URLs here
const urls = [...pages].filter((url) => !STATUS_CODE_PAGE_REGEXP.test(url));
urls.sort((a, b) => a.localeCompare(b, 'en', { numeric: true })); // sort alphabetically so sitemap is same each time
let sitemap = `<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">`;
for (const url of urls) {
sitemap += `<url><loc>${url}</loc></url>`;
}
sitemap += `</urlset>\n`;
return sitemap;
}
Migrate to new config (#2962) * wip: config migration * fix: formatting * refactor: projectRoot -> root * refactor: pageUrlFormat -> format * refactor: buildOptions.site -> site * refactor: public -> publicDir * refactor: dist -> outDir * refactor: styleOptions -> style * fix: some dist tests -> outDir * refactor: remove legacyBuild (with TODOs) * refactor: more legacyBuild cleanup * refactor: server host and port * fix: remove experimentalStaticBuild CLI flag * refactor: src -> srcDir * refactor: devOptions.trailing -> trailing * refactor: remove sitemap + related flags * refactor: experimentalSSR -> experimental.ssr * fix: last devOptions * refactor: drafts -> markdown.drafts * fix: TS error on port as const * refactor: remove pages * refactor: more --project-root updates * refactor: markdownOptions -> markdown * fix: remaining type errors * feat: update AstroUserConfig * refactor: update CLI flag mapper + server mapper * fix: loadFixture projectRoot * fix: merge CLI flags before validating / transforming * wip: attempt to fix bad createRouteManifest config * refactor: combine config.base and config.site * fix: skip route manifest test for now * fix: site and base handling * refactor: update failing config testes * fix: build failure * feat: update config types with migration help * chore: update types * fix(deno): update deno fixture * chore: remove config migration logic * chore: remove logLevel * chore: clean-up config types * chore: update config warning * chore: add changeset * Sitemap Integration (#2965) * feat: add sitemap filter config option * feat: add canonicalURL sitemap config option * docs: update sitemap README * fix: update for new config * fix: filter not being applied * chore: changeset Co-authored-by: bholmesdev <hey@bholmes.dev> * fred pass * fix: Astro.resolve typo * fix: public => publicDir Co-authored-by: bholmesdev <hey@bholmes.dev> Co-authored-by: Fred K. Schott <fkschott@gmail.com>
2022-04-02 18:29:59 +00:00
export default function createPlugin({ filter, canonicalURL }: SitemapOptions = {}): AstroIntegration {
let config: AstroConfig;
return {
name: '@astrojs/sitemap',
hooks: {
'astro:config:done': async ({ config: _config }) => {
config = _config;
},
'astro:build:done': async ({ pages, dir }) => {
Migrate to new config (#2962) * wip: config migration * fix: formatting * refactor: projectRoot -> root * refactor: pageUrlFormat -> format * refactor: buildOptions.site -> site * refactor: public -> publicDir * refactor: dist -> outDir * refactor: styleOptions -> style * fix: some dist tests -> outDir * refactor: remove legacyBuild (with TODOs) * refactor: more legacyBuild cleanup * refactor: server host and port * fix: remove experimentalStaticBuild CLI flag * refactor: src -> srcDir * refactor: devOptions.trailing -> trailing * refactor: remove sitemap + related flags * refactor: experimentalSSR -> experimental.ssr * fix: last devOptions * refactor: drafts -> markdown.drafts * fix: TS error on port as const * refactor: remove pages * refactor: more --project-root updates * refactor: markdownOptions -> markdown * fix: remaining type errors * feat: update AstroUserConfig * refactor: update CLI flag mapper + server mapper * fix: loadFixture projectRoot * fix: merge CLI flags before validating / transforming * wip: attempt to fix bad createRouteManifest config * refactor: combine config.base and config.site * fix: skip route manifest test for now * fix: site and base handling * refactor: update failing config testes * fix: build failure * feat: update config types with migration help * chore: update types * fix(deno): update deno fixture * chore: remove config migration logic * chore: remove logLevel * chore: clean-up config types * chore: update config warning * chore: add changeset * Sitemap Integration (#2965) * feat: add sitemap filter config option * feat: add canonicalURL sitemap config option * docs: update sitemap README * fix: update for new config * fix: filter not being applied * chore: changeset Co-authored-by: bholmesdev <hey@bholmes.dev> * fred pass * fix: Astro.resolve typo * fix: public => publicDir Co-authored-by: bholmesdev <hey@bholmes.dev> Co-authored-by: Fred K. Schott <fkschott@gmail.com>
2022-04-02 18:29:59 +00:00
const finalSiteUrl = canonicalURL || config.site;
if (!finalSiteUrl) {
Migrate to new config (#2962) * wip: config migration * fix: formatting * refactor: projectRoot -> root * refactor: pageUrlFormat -> format * refactor: buildOptions.site -> site * refactor: public -> publicDir * refactor: dist -> outDir * refactor: styleOptions -> style * fix: some dist tests -> outDir * refactor: remove legacyBuild (with TODOs) * refactor: more legacyBuild cleanup * refactor: server host and port * fix: remove experimentalStaticBuild CLI flag * refactor: src -> srcDir * refactor: devOptions.trailing -> trailing * refactor: remove sitemap + related flags * refactor: experimentalSSR -> experimental.ssr * fix: last devOptions * refactor: drafts -> markdown.drafts * fix: TS error on port as const * refactor: remove pages * refactor: more --project-root updates * refactor: markdownOptions -> markdown * fix: remaining type errors * feat: update AstroUserConfig * refactor: update CLI flag mapper + server mapper * fix: loadFixture projectRoot * fix: merge CLI flags before validating / transforming * wip: attempt to fix bad createRouteManifest config * refactor: combine config.base and config.site * fix: skip route manifest test for now * fix: site and base handling * refactor: update failing config testes * fix: build failure * feat: update config types with migration help * chore: update types * fix(deno): update deno fixture * chore: remove config migration logic * chore: remove logLevel * chore: clean-up config types * chore: update config warning * chore: add changeset * Sitemap Integration (#2965) * feat: add sitemap filter config option * feat: add canonicalURL sitemap config option * docs: update sitemap README * fix: update for new config * fix: filter not being applied * chore: changeset Co-authored-by: bholmesdev <hey@bholmes.dev> * fred pass * fix: Astro.resolve typo * fix: public => publicDir Co-authored-by: bholmesdev <hey@bholmes.dev> Co-authored-by: Fred K. Schott <fkschott@gmail.com>
2022-04-02 18:29:59 +00:00
console.warn('The Sitemap integration requires either the `site` astro.config option or `canonicalURL` integration option. Skipping.');
return;
}
Migrate to new config (#2962) * wip: config migration * fix: formatting * refactor: projectRoot -> root * refactor: pageUrlFormat -> format * refactor: buildOptions.site -> site * refactor: public -> publicDir * refactor: dist -> outDir * refactor: styleOptions -> style * fix: some dist tests -> outDir * refactor: remove legacyBuild (with TODOs) * refactor: more legacyBuild cleanup * refactor: server host and port * fix: remove experimentalStaticBuild CLI flag * refactor: src -> srcDir * refactor: devOptions.trailing -> trailing * refactor: remove sitemap + related flags * refactor: experimentalSSR -> experimental.ssr * fix: last devOptions * refactor: drafts -> markdown.drafts * fix: TS error on port as const * refactor: remove pages * refactor: more --project-root updates * refactor: markdownOptions -> markdown * fix: remaining type errors * feat: update AstroUserConfig * refactor: update CLI flag mapper + server mapper * fix: loadFixture projectRoot * fix: merge CLI flags before validating / transforming * wip: attempt to fix bad createRouteManifest config * refactor: combine config.base and config.site * fix: skip route manifest test for now * fix: site and base handling * refactor: update failing config testes * fix: build failure * feat: update config types with migration help * chore: update types * fix(deno): update deno fixture * chore: remove config migration logic * chore: remove logLevel * chore: clean-up config types * chore: update config warning * chore: add changeset * Sitemap Integration (#2965) * feat: add sitemap filter config option * feat: add canonicalURL sitemap config option * docs: update sitemap README * fix: update for new config * fix: filter not being applied * chore: changeset Co-authored-by: bholmesdev <hey@bholmes.dev> * fred pass * fix: Astro.resolve typo * fix: public => publicDir Co-authored-by: bholmesdev <hey@bholmes.dev> Co-authored-by: Fred K. Schott <fkschott@gmail.com>
2022-04-02 18:29:59 +00:00
let pageUrls = pages.map((p) => new URL(p.pathname, finalSiteUrl).href);
if (filter) {
pageUrls = pageUrls.filter((page: string) => filter(page));
}
const sitemapContent = generateSitemap(pageUrls);
fs.writeFileSync(new URL('sitemap.xml', dir), sitemapContent);
},
},
};
}