summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Atila Fassina <atilafassina@gmail.com> 2023-05-03 18:19:45 +0200
committerGravatar GitHub <noreply@github.com> 2023-05-03 12:19:45 -0400
commitad907196cb42f21d9540ae0d77aa742bf7adf030 (patch)
tree54e56261b5a08bb2fa021c721b0877394231ef33
parentcac4a321e814fb805eb0e3ced469e25261a50885 (diff)
downloadastro-ad907196cb42f21d9540ae0d77aa742bf7adf030.tar.gz
astro-ad907196cb42f21d9540ae0d77aa742bf7adf030.tar.zst
astro-ad907196cb42f21d9540ae0d77aa742bf7adf030.zip
Sitemap: support SSR routes (#6534)
* feat(sitemap): support SSR generated routes * feat(sitemap): add changeset for SSR support * refactor: move logic to `astro:build:done` * generate route to obey `trailingSlash` setting * add logic to respect "directory" build format * integration(sitemap): add unit test for ssr support
-rw-r--r--.changeset/chatty-dolls-visit.md5
-rw-r--r--packages/integrations/sitemap/package.json1
-rw-r--r--packages/integrations/sitemap/src/index.ts54
-rw-r--r--packages/integrations/sitemap/test/fixtures/ssr/astro.config.mjs12
-rw-r--r--packages/integrations/sitemap/test/fixtures/ssr/package.json9
-rw-r--r--packages/integrations/sitemap/test/fixtures/ssr/src/pages/one.astro8
-rw-r--r--packages/integrations/sitemap/test/fixtures/ssr/src/pages/two.astro8
-rw-r--r--packages/integrations/sitemap/test/ssr.test.js22
-rw-r--r--pnpm-lock.yaml12
9 files changed, 113 insertions, 18 deletions
diff --git a/.changeset/chatty-dolls-visit.md b/.changeset/chatty-dolls-visit.md
new file mode 100644
index 000000000..6b9e53e88
--- /dev/null
+++ b/.changeset/chatty-dolls-visit.md
@@ -0,0 +1,5 @@
+---
+'@astrojs/sitemap': minor
+---
+
+Adds support to SSR routes to sitemap generation.
diff --git a/packages/integrations/sitemap/package.json b/packages/integrations/sitemap/package.json
index afd959a62..7c465494e 100644
--- a/packages/integrations/sitemap/package.json
+++ b/packages/integrations/sitemap/package.json
@@ -37,6 +37,7 @@
"zod": "^3.17.3"
},
"devDependencies": {
+ "@astrojs/node": "workspace:*",
"astro": "workspace:*",
"astro-scripts": "workspace:*",
"chai": "^4.3.6",
diff --git a/packages/integrations/sitemap/src/index.ts b/packages/integrations/sitemap/src/index.ts
index e6e45ddd1..0814ae0e1 100644
--- a/packages/integrations/sitemap/src/index.ts
+++ b/packages/integrations/sitemap/src/index.ts
@@ -51,6 +51,8 @@ const OUTFILE = 'sitemap-index.xml';
const createPlugin = (options?: SitemapOptions): AstroIntegration => {
let config: AstroConfig;
+ const logger = new Logger(PKG_NAME);
+
return {
name: PKG_NAME,
@@ -59,10 +61,15 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
config = cfg;
},
- 'astro:build:done': async ({ dir, pages }) => {
- const logger = new Logger(PKG_NAME);
-
+ 'astro:build:done': async ({ dir, routes }) => {
try {
+ if (!config.site) {
+ logger.warn(
+ 'The Sitemap integration requires the `site` astro.config option. Skipping.'
+ );
+ return;
+ }
+
const opts = validateOptions(config.site, options);
const { filter, customPages, serialize, entryLimit } = opts;
@@ -78,12 +85,30 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
return;
}
- let pageUrls = pages.map((p) => {
- if (p.pathname !== '' && !finalSiteUrl.pathname.endsWith('/'))
- finalSiteUrl.pathname += '/';
- const path = finalSiteUrl.pathname + p.pathname;
- return new URL(path, finalSiteUrl).href;
- });
+ let pageUrls = routes.reduce<string[]>((urls, r) => {
+ /**
+ * Dynamic URLs have entries with `undefined` pathnames
+ */
+ if (r.pathname) {
+ /**
+ * remove the initial slash from relative pathname
+ * because `finalSiteUrl` always has trailing slash
+ */
+ const path = finalSiteUrl.pathname + r.generate(r.pathname).substring(1);
+
+ let newUrl = new URL(path, finalSiteUrl).href;
+
+ if (config.trailingSlash === 'never') {
+ urls.push(newUrl);
+ } else if (config.build.format === 'directory' && !newUrl.endsWith('/')) {
+ urls.push(newUrl + '/');
+ } else {
+ urls.push(newUrl);
+ }
+ }
+
+ return urls;
+ }, []);
try {
if (filter) {
@@ -95,18 +120,11 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
}
if (customPages) {
- pageUrls = [...pageUrls, ...customPages];
+ pageUrls = Array.from(new Set([...pageUrls, ...customPages]));
}
if (pageUrls.length === 0) {
- // offer suggestion for SSR users
- if (config.output !== 'static') {
- logger.warn(
- `No pages found! We can only detect sitemap routes for "static" builds. Since you are using an SSR adapter, we recommend manually listing your sitemap routes using the "customPages" integration option.\n\nExample: \`sitemap({ customPages: ['https://example.com/route'] })\``
- );
- } else {
- logger.warn(`No pages found!\n\`${OUTFILE}\` not created.`);
- }
+ logger.warn(`No pages found!\n\`${OUTFILE}\` not created.`);
return;
}
diff --git a/packages/integrations/sitemap/test/fixtures/ssr/astro.config.mjs b/packages/integrations/sitemap/test/fixtures/ssr/astro.config.mjs
new file mode 100644
index 000000000..d914d4357
--- /dev/null
+++ b/packages/integrations/sitemap/test/fixtures/ssr/astro.config.mjs
@@ -0,0 +1,12 @@
+import { defineConfig } from 'astro/config';
+import sitemap from '@astrojs/sitemap';
+import nodeServer from '@astrojs/node'
+
+export default defineConfig({
+ integrations: [sitemap()],
+ site: 'http://example.com',
+ output: 'server',
+ adapter: nodeServer({
+ mode: "standalone"
+ })
+})
diff --git a/packages/integrations/sitemap/test/fixtures/ssr/package.json b/packages/integrations/sitemap/test/fixtures/ssr/package.json
new file mode 100644
index 000000000..980e02e73
--- /dev/null
+++ b/packages/integrations/sitemap/test/fixtures/ssr/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/sitemap-trailing-slash",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*",
+ "@astrojs/sitemap": "workspace:*"
+ }
+}
diff --git a/packages/integrations/sitemap/test/fixtures/ssr/src/pages/one.astro b/packages/integrations/sitemap/test/fixtures/ssr/src/pages/one.astro
new file mode 100644
index 000000000..0c7fb90a7
--- /dev/null
+++ b/packages/integrations/sitemap/test/fixtures/ssr/src/pages/one.astro
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>One</title>
+ </head>
+ <body>
+ <h1>One</h1>
+ </body>
+</html>
diff --git a/packages/integrations/sitemap/test/fixtures/ssr/src/pages/two.astro b/packages/integrations/sitemap/test/fixtures/ssr/src/pages/two.astro
new file mode 100644
index 000000000..e7ba9910e
--- /dev/null
+++ b/packages/integrations/sitemap/test/fixtures/ssr/src/pages/two.astro
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>Two</title>
+ </head>
+ <body>
+ <h1>Two</h1>
+ </body>
+</html>
diff --git a/packages/integrations/sitemap/test/ssr.test.js b/packages/integrations/sitemap/test/ssr.test.js
new file mode 100644
index 000000000..e6f8412d5
--- /dev/null
+++ b/packages/integrations/sitemap/test/ssr.test.js
@@ -0,0 +1,22 @@
+import { loadFixture, readXML } from './test-utils.js';
+import { expect } from 'chai';
+
+describe('SSR support', () => {
+ /** @type {import('./test-utils.js').Fixture} */
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/ssr/',
+ });
+ await fixture.build();
+ });
+
+ it('SSR pages require zero config', async () => {
+ const data = await readXML(fixture.readFile('/client/sitemap-0.xml'));
+ const urls = data.urlset.url;
+
+ expect(urls[0].loc[0]).to.equal('http://example.com/one/');
+ expect(urls[1].loc[0]).to.equal('http://example.com/two/');
+ });
+});
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 49ad594ee..c770aa864 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -4505,6 +4505,9 @@ importers:
specifier: ^3.17.3
version: 3.20.6
devDependencies:
+ '@astrojs/node':
+ specifier: workspace:*
+ version: link:../node
astro:
specifier: workspace:*
version: link:../../astro
@@ -4521,6 +4524,15 @@ importers:
specifier: 0.5.0
version: 0.5.0
+ packages/integrations/sitemap/test/fixtures/ssr:
+ dependencies:
+ '@astrojs/sitemap':
+ specifier: workspace:*
+ version: link:../../..
+ astro:
+ specifier: workspace:*
+ version: link:../../../../../astro
+
packages/integrations/sitemap/test/fixtures/trailing-slash:
dependencies:
'@astrojs/sitemap':