From c4ed90598b28f0b35768c96d244f4484c79fcc5a Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Mon, 8 May 2023 18:11:55 +0100 Subject: [PATCH] fix(sitemap): use pages to build the sitemap --- .changeset/silly-impalas-shout.md | 5 ++ packages/integrations/sitemap/src/index.ts | 47 ++++++++++++------- .../integrations/sitemap/test/content.test.js | 23 +++++++++ .../test/fixtures/content/astro.config.mjs | 10 ++++ .../test/fixtures/content/package.json | 10 ++++ .../fixtures/content/src/content/blog/bar.md | 5 ++ .../fixtures/content/src/content/blog/foo.md | 5 ++ .../fixtures/content/src/content/config.ts | 20 ++++++++ .../content/src/pages/blog/[...slug].astro | 18 +++++++ .../fixtures/content/src/pages/index.astro | 0 .../test/fixtures/ssr/astro.config.mjs | 2 +- .../sitemap/test/fixtures/ssr/package.json | 3 +- pnpm-lock.yaml | 15 ++++++ 13 files changed, 143 insertions(+), 20 deletions(-) create mode 100644 .changeset/silly-impalas-shout.md create mode 100644 packages/integrations/sitemap/test/content.test.js create mode 100644 packages/integrations/sitemap/test/fixtures/content/astro.config.mjs create mode 100644 packages/integrations/sitemap/test/fixtures/content/package.json create mode 100644 packages/integrations/sitemap/test/fixtures/content/src/content/blog/bar.md create mode 100644 packages/integrations/sitemap/test/fixtures/content/src/content/blog/foo.md create mode 100644 packages/integrations/sitemap/test/fixtures/content/src/content/config.ts create mode 100644 packages/integrations/sitemap/test/fixtures/content/src/pages/blog/[...slug].astro create mode 100644 packages/integrations/sitemap/test/fixtures/content/src/pages/index.astro diff --git a/.changeset/silly-impalas-shout.md b/.changeset/silly-impalas-shout.md new file mode 100644 index 000000000000..2664c5cb1f94 --- /dev/null +++ b/.changeset/silly-impalas-shout.md @@ -0,0 +1,5 @@ +--- +'@astrojs/sitemap': patch +--- + +Correctly emit sitemap when building website in SSG diff --git a/packages/integrations/sitemap/src/index.ts b/packages/integrations/sitemap/src/index.ts index 0814ae0e1a3d..2e333b8b4258 100644 --- a/packages/integrations/sitemap/src/index.ts +++ b/packages/integrations/sitemap/src/index.ts @@ -61,7 +61,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => { config = cfg; }, - 'astro:build:done': async ({ dir, routes }) => { + 'astro:build:done': async ({ dir, pages, routes }) => { try { if (!config.site) { logger.warn( @@ -84,31 +84,42 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => { ); return; } - - let pageUrls = routes.reduce((urls, r) => { - /** - * Dynamic URLs have entries with `undefined` pathnames - */ - if (r.pathname) { + let paths; + if (pages.length > 0) { + paths = pages.map((page) => { /** * remove the initial slash from relative pathname * because `finalSiteUrl` always has trailing slash */ - const path = finalSiteUrl.pathname + r.generate(r.pathname).substring(1); + const path = finalSiteUrl.pathname + page.pathname; - let newUrl = new URL(path, finalSiteUrl).href; + return new URL(path, finalSiteUrl).href; + }); + } else { + paths = routes.reduce((urls, route) => { + if (route.pathname) { + const path = finalSiteUrl.pathname + route.pathname.substring(1); - if (config.trailingSlash === 'never') { - urls.push(newUrl); - } else if (config.build.format === 'directory' && !newUrl.endsWith('/')) { - urls.push(newUrl + '/'); - } else { - urls.push(newUrl); + urls.push(new URL(path, finalSiteUrl).href); } - } + return urls; + }, []); + } - return urls; - }, []); + let pageUrls = paths.map((path) => { + /** + * remove the initial slash from relative pathname + * because `finalSiteUrl` always has trailing slash + */ + + if (config.trailingSlash === 'never') { + return path; + } else if (config.build.format === 'directory' && !path.endsWith('/')) { + return path + '/'; + } else { + return path; + } + }); try { if (filter) { diff --git a/packages/integrations/sitemap/test/content.test.js b/packages/integrations/sitemap/test/content.test.js new file mode 100644 index 000000000000..4a36ed3c0894 --- /dev/null +++ b/packages/integrations/sitemap/test/content.test.js @@ -0,0 +1,23 @@ +import { loadFixture, readXML } from './test-utils.js'; +import { expect } from 'chai'; + +describe('Content collections support', () => { + /** @type {import('./test-utils.js').Fixture} */ + let fixture; + + before(async () => { + fixture = await loadFixture({ + root: './fixtures/content/', + }); + await fixture.build(); + }); + + it('SSR pages require zero config', async () => { + const data = await readXML(fixture.readFile('/sitemap-0.xml')); + const urls = data.urlset.url; + + expect(urls[0].loc[0]).to.equal('https://example.com/'); + expect(urls[1].loc[0]).to.equal('https://example.com/blog/bar/'); + expect(urls[2].loc[0]).to.equal('https://example.com/blog/foo/'); + }); +}); diff --git a/packages/integrations/sitemap/test/fixtures/content/astro.config.mjs b/packages/integrations/sitemap/test/fixtures/content/astro.config.mjs new file mode 100644 index 000000000000..1a9364dcc2f4 --- /dev/null +++ b/packages/integrations/sitemap/test/fixtures/content/astro.config.mjs @@ -0,0 +1,10 @@ +import { defineConfig } from 'astro/config'; +import mdx from '@astrojs/mdx'; +import sitemap from '@astrojs/sitemap'; + +// https://astro.build/config +export default defineConfig({ + site: 'https://example.com', + integrations: [mdx(), sitemap()], +}); + diff --git a/packages/integrations/sitemap/test/fixtures/content/package.json b/packages/integrations/sitemap/test/fixtures/content/package.json new file mode 100644 index 000000000000..a6101e73160d --- /dev/null +++ b/packages/integrations/sitemap/test/fixtures/content/package.json @@ -0,0 +1,10 @@ +{ + "name": "@test/sitemap-content", + "version": "0.0.0", + "private": true, + "dependencies": { + "astro": "workspace:*", + "@astrojs/sitemap": "workspace:*", + "@astrojs/mdx": "workspace:*" + } +} diff --git a/packages/integrations/sitemap/test/fixtures/content/src/content/blog/bar.md b/packages/integrations/sitemap/test/fixtures/content/src/content/blog/bar.md new file mode 100644 index 000000000000..48a964b20ea5 --- /dev/null +++ b/packages/integrations/sitemap/test/fixtures/content/src/content/blog/bar.md @@ -0,0 +1,5 @@ +--- +title: "First post" +description: "Lorem ipsum dolor sit amet" +pubDate: "Jul 08 2022" +--- \ No newline at end of file diff --git a/packages/integrations/sitemap/test/fixtures/content/src/content/blog/foo.md b/packages/integrations/sitemap/test/fixtures/content/src/content/blog/foo.md new file mode 100644 index 000000000000..d74b79b42122 --- /dev/null +++ b/packages/integrations/sitemap/test/fixtures/content/src/content/blog/foo.md @@ -0,0 +1,5 @@ +--- +title: "Markdown Style Guide" +description: "Here is a sample of some basic Markdown syntax that can be used when writing Markdown content in Astro." +pubDate: "Jul 01 2022" +--- \ No newline at end of file diff --git a/packages/integrations/sitemap/test/fixtures/content/src/content/config.ts b/packages/integrations/sitemap/test/fixtures/content/src/content/config.ts new file mode 100644 index 000000000000..c249c6568438 --- /dev/null +++ b/packages/integrations/sitemap/test/fixtures/content/src/content/config.ts @@ -0,0 +1,20 @@ +import { defineCollection, z } from 'astro:content'; + +const blog = defineCollection({ + // Type-check frontmatter using a schema + schema: z.object({ + title: z.string(), + description: z.string(), + // Transform string to Date object + pubDate: z + .string() + .or(z.date()) + .transform((val) => new Date(val)), + updatedDate: z + .string() + .optional() + .transform((str) => (str ? new Date(str) : undefined)), + }), +}); + +export const collections = { blog }; diff --git a/packages/integrations/sitemap/test/fixtures/content/src/pages/blog/[...slug].astro b/packages/integrations/sitemap/test/fixtures/content/src/pages/blog/[...slug].astro new file mode 100644 index 000000000000..03ea58719b85 --- /dev/null +++ b/packages/integrations/sitemap/test/fixtures/content/src/pages/blog/[...slug].astro @@ -0,0 +1,18 @@ +--- +import { CollectionEntry, getCollection } from 'astro:content'; + +export async function getStaticPaths() { + const posts = await getCollection('blog'); + return posts.map((post) => ({ + params: { slug: post.slug }, + props: post, + })); +} +type Props = CollectionEntry<'blog'>; + +const post = Astro.props; +const { Content } = await post.render(); +--- + +

{post.data.title}

+ diff --git a/packages/integrations/sitemap/test/fixtures/content/src/pages/index.astro b/packages/integrations/sitemap/test/fixtures/content/src/pages/index.astro new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/integrations/sitemap/test/fixtures/ssr/astro.config.mjs b/packages/integrations/sitemap/test/fixtures/ssr/astro.config.mjs index d914d4357e9f..0d610984b67e 100644 --- a/packages/integrations/sitemap/test/fixtures/ssr/astro.config.mjs +++ b/packages/integrations/sitemap/test/fixtures/ssr/astro.config.mjs @@ -3,7 +3,7 @@ import sitemap from '@astrojs/sitemap'; import nodeServer from '@astrojs/node' export default defineConfig({ - integrations: [sitemap()], + integrations: [sitemap()], site: 'http://example.com', output: 'server', adapter: nodeServer({ diff --git a/packages/integrations/sitemap/test/fixtures/ssr/package.json b/packages/integrations/sitemap/test/fixtures/ssr/package.json index 4c4c68285e96..1ca03518276c 100644 --- a/packages/integrations/sitemap/test/fixtures/ssr/package.json +++ b/packages/integrations/sitemap/test/fixtures/ssr/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "astro": "workspace:*", - "@astrojs/sitemap": "workspace:*" + "@astrojs/sitemap": "workspace:*", + "@astrojs/node": "workspace:*" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8d8c3410f00d..e259b50adc48 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4566,8 +4566,23 @@ importers: specifier: 0.5.0 version: 0.5.0 + packages/integrations/sitemap/test/fixtures/content: + dependencies: + '@astrojs/mdx': + specifier: workspace:* + version: link:../../../../mdx + '@astrojs/sitemap': + specifier: workspace:* + version: link:../../.. + astro: + specifier: workspace:* + version: link:../../../../../astro + packages/integrations/sitemap/test/fixtures/ssr: dependencies: + '@astrojs/node': + specifier: workspace:* + version: link:../../../../node '@astrojs/sitemap': specifier: workspace:* version: link:../../..