Skip to content

Commit fbe1bc5

Browse files
sondr3bluwyflorian-lefebvre
authored
feat(sitemap): add xslURL to enable styling (#11485)
* feat(sitemap): add xslURL to enable styling * Add test * Update .changeset/proud-horses-cry.md --------- Co-authored-by: bluwy <bjornlu.dev@gmail.com> Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev>
1 parent 42037f3 commit fbe1bc5

5 files changed

Lines changed: 36 additions & 7 deletions

File tree

.changeset/proud-horses-cry.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@astrojs/sitemap': minor
3+
---
4+
5+
Adds new `xslURL` option to enable styling of sitemaps

packages/integrations/sitemap/src/index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
8888

8989
const { filter, customPages, serialize, entryLimit } = opts;
9090

91-
let finalSiteUrl = new URL(config.base, config.site);
91+
const finalSiteUrl = new URL(config.base, config.site);
9292
const shouldIgnoreStatus = isStatusCodePage(Object.keys(opts.i18n?.locales ?? {}));
9393
let pageUrls = pages
9494
.filter((p) => !shouldIgnoreStatus(p.pathname))
@@ -100,7 +100,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
100100
return new URL(fullPath, finalSiteUrl).href;
101101
});
102102

103-
let routeUrls = routes.reduce<string[]>((urls, r) => {
103+
const routeUrls = routes.reduce<string[]>((urls, r) => {
104104
// Only expose pages, not endpoints or redirects
105105
if (r.type !== 'page') return urls;
106106

@@ -116,7 +116,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
116116
if (fullPath.endsWith('/')) fullPath += r.generate(r.pathname).substring(1);
117117
else fullPath += r.generate(r.pathname);
118118

119-
let newUrl = new URL(fullPath, finalSiteUrl).href;
119+
const newUrl = new URL(fullPath, finalSiteUrl).href;
120120

121121
if (config.trailingSlash === 'never') {
122122
urls.push(newUrl);
@@ -168,13 +168,15 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
168168
}
169169
}
170170
const destDir = fileURLToPath(dir);
171+
const xslURL = opts.xslURL ? new URL(opts.xslURL, finalSiteUrl).href : undefined;
171172
await writeSitemap(
172173
{
173174
hostname: finalSiteUrl.href,
174175
destinationDir: destDir,
175176
publicBasePath: config.base,
176177
sourceData: urlData,
177178
limit: entryLimit,
179+
xslURL: xslURL,
178180
},
179181
config,
180182
);

packages/integrations/sitemap/src/schema.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const SitemapOptionsSchema = z
99
filter: z.function().args(z.string()).returns(z.boolean()).optional(),
1010
customPages: z.string().url().array().optional(),
1111
canonicalURL: z.string().url().optional(),
12+
xslURL: z.string().optional(),
1213

1314
i18n: z
1415
.object({

packages/integrations/sitemap/src/write-sitemap.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type WriteSitemapConfig = {
1717
destinationDir: string;
1818
publicBasePath?: string;
1919
limit?: number;
20+
xslURL?: string;
2021
};
2122

2223
// adapted from sitemap.js/sitemap-simple
@@ -28,6 +29,7 @@ export async function writeSitemap(
2829
destinationDir,
2930
limit = 50000,
3031
publicBasePath = './',
32+
xslURL: xslUrl,
3133
}: WriteSitemapConfig,
3234
astroConfig: AstroConfig,
3335
) {
@@ -38,6 +40,7 @@ export async function writeSitemap(
3840
getSitemapStream: (i) => {
3941
const sitemapStream = new SitemapStream({
4042
hostname,
43+
xslUrl,
4144
});
4245
const path = `./sitemap-${i}.xml`;
4346
const writePath = resolve(destinationDir, path);
@@ -63,7 +66,7 @@ export async function writeSitemap(
6366
},
6467
});
6568

66-
let src = Readable.from(sourceData);
69+
const src = Readable.from(sourceData);
6770
const indexPath = resolve(destinationDir, `./sitemap-index.xml`);
6871
return promisify(pipeline)(src, sitemapAndIndexStream, createWriteStream(indexPath));
6972
}

packages/integrations/sitemap/test/filter.test.js renamed to packages/integrations/sitemap/test/config.test.js

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { before, describe, it } from 'node:test';
33
import { sitemap } from './fixtures/static/deps.mjs';
44
import { loadFixture, readXML } from './test-utils.js';
55

6-
describe('Filter support', () => {
6+
describe('Config', () => {
77
/** @type {import('./test-utils.js').Fixture} */
88
let fixture;
99

@@ -14,17 +14,26 @@ describe('Filter support', () => {
1414
integrations: [
1515
sitemap({
1616
filter: (page) => page === 'http://example.com/one/',
17+
xslURL: '/sitemap.xsl',
1718
}),
1819
],
1920
});
2021
await fixture.build();
2122
});
2223

23-
it('Just one page is added', async () => {
24+
it('filter: Just one page is added', async () => {
2425
const data = await readXML(fixture.readFile('/sitemap-0.xml'));
2526
const urls = data.urlset.url;
2627
assert.equal(urls.length, 1);
2728
});
29+
30+
it('xslURL: Includes xml-stylsheet', async () => {
31+
const xml = await fixture.readFile('/sitemap-0.xml');
32+
assert.ok(
33+
xml.includes('<?xml-stylesheet type="text/xsl" href="http://example.com/sitemap.xsl"?>'),
34+
xml,
35+
);
36+
});
2837
});
2938

3039
describe('SSR', () => {
@@ -34,16 +43,25 @@ describe('Filter support', () => {
3443
integrations: [
3544
sitemap({
3645
filter: (page) => page === 'http://example.com/one/',
46+
xslURL: '/sitemap.xsl',
3747
}),
3848
],
3949
});
4050
await fixture.build();
4151
});
4252

43-
it('Just one page is added', async () => {
53+
it('filter: Just one page is added', async () => {
4454
const data = await readXML(fixture.readFile('/client/sitemap-0.xml'));
4555
const urls = data.urlset.url;
4656
assert.equal(urls.length, 1);
4757
});
58+
59+
it('xslURL: Includes xml-stylsheet', async () => {
60+
const xml = await fixture.readFile('/client/sitemap-0.xml');
61+
assert.ok(
62+
xml.includes('<?xml-stylesheet type="text/xsl" href="http://example.com/sitemap.xsl"?>'),
63+
xml,
64+
);
65+
});
4866
});
4967
});

0 commit comments

Comments
 (0)