diff --git a/packages/integrations/sitemap/package.json b/packages/integrations/sitemap/package.json
index abf9f263b8b6..fa471256d8f5 100644
--- a/packages/integrations/sitemap/package.json
+++ b/packages/integrations/sitemap/package.json
@@ -34,6 +34,7 @@
},
"dependencies": {
"sitemap": "^7.1.1",
+ "stream-replace-string": "^2.0.0",
"zod": "^3.22.4"
},
"devDependencies": {
diff --git a/packages/integrations/sitemap/src/index.ts b/packages/integrations/sitemap/src/index.ts
index b0548d8f114c..a2fae5b5ade4 100644
--- a/packages/integrations/sitemap/src/index.ts
+++ b/packages/integrations/sitemap/src/index.ts
@@ -2,11 +2,11 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url';
import type { AstroConfig, AstroIntegration } from 'astro';
import type { EnumChangefreq, LinkItem as LinkItemBase, SitemapItemLoose } from 'sitemap';
-import { simpleSitemapAndIndex } from 'sitemap';
import { ZodError } from 'zod';
-import { generateSitemap } from './generate-sitemap.js';
import { validateOptions } from './validate-options.js';
+import { generateSitemap } from './generate-sitemap.js';
+import { writeSitemap } from './write-sitemap.js';
export { EnumChangefreq as ChangeFreqEnum } from 'sitemap';
export type ChangeFreq = `${EnumChangefreq}`;
@@ -167,14 +167,13 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
}
}
const destDir = fileURLToPath(dir);
- await simpleSitemapAndIndex({
+ await writeSitemap({
hostname: finalSiteUrl.href,
destinationDir: destDir,
publicBasePath: config.base,
sourceData: urlData,
- limit: entryLimit,
- gzip: false,
- });
+ limit: entryLimit
+ }, config)
logger.info(`\`${OUTFILE}\` created at \`${path.relative(process.cwd(), destDir)}\``);
} catch (err) {
if (err instanceof ZodError) {
diff --git a/packages/integrations/sitemap/src/write-sitemap.ts b/packages/integrations/sitemap/src/write-sitemap.ts
new file mode 100644
index 000000000000..d55d4fc50b61
--- /dev/null
+++ b/packages/integrations/sitemap/src/write-sitemap.ts
@@ -0,0 +1,69 @@
+import { normalize, resolve } from 'path';
+import { createWriteStream, type WriteStream } from 'fs'
+import { mkdir } from 'fs/promises';
+import { promisify } from 'util';
+import { Readable, pipeline } from 'stream';
+import replace from 'stream-replace-string'
+
+import { SitemapAndIndexStream, SitemapStream } from 'sitemap';
+
+import type { AstroConfig } from 'astro';
+import type { SitemapItem } from "./index.js";
+
+type WriteSitemapConfig = {
+ hostname: string;
+ sitemapHostname?: string;
+ sourceData: SitemapItem[];
+ destinationDir: string;
+ publicBasePath?: string;
+ limit?: number;
+}
+
+// adapted from sitemap.js/sitemap-simple
+export async function writeSitemap({ hostname, sitemapHostname = hostname,
+sourceData, destinationDir, limit = 50000, publicBasePath = './', }: WriteSitemapConfig, astroConfig: AstroConfig) {
+
+ await mkdir(destinationDir, { recursive: true })
+
+ const sitemapAndIndexStream = new SitemapAndIndexStream({
+ limit,
+ getSitemapStream: (i) => {
+ const sitemapStream = new SitemapStream({
+ hostname,
+ });
+ const path = `./sitemap-${i}.xml`;
+ const writePath = resolve(destinationDir, path);
+ if (!publicBasePath.endsWith('/')) {
+ publicBasePath += '/';
+ }
+ const publicPath = normalize(publicBasePath + path);
+
+ let stream: WriteStream
+ if (astroConfig.trailingSlash === 'never' || astroConfig.build.format === 'file') {
+ // workaround for trailing slash issue in sitemap.js: https://github.com/ekalinin/sitemap.js/issues/403
+ const host = hostname.endsWith('/') ? hostname.slice(0, -1) : hostname
+ const searchStr = `${host}/`
+ const replaceStr = `${host}`
+ stream = sitemapStream.pipe(replace(searchStr, replaceStr)).pipe(createWriteStream(writePath))
+ } else {
+ stream = sitemapStream.pipe(createWriteStream(writePath))
+ }
+
+ return [
+ new URL(
+ publicPath,
+ sitemapHostname
+ ).toString(),
+ sitemapStream,
+ stream,
+ ];
+ },
+ });
+
+ let src = Readable.from(sourceData)
+ const indexPath = resolve(
+ destinationDir,
+ `./sitemap-index.xml`
+ );
+ return promisify(pipeline)(src, sitemapAndIndexStream, createWriteStream(indexPath));
+}
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 84b9c8e649a0..d3a72f71b956 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -4873,6 +4873,9 @@ importers:
sitemap:
specifier: ^7.1.1
version: 7.1.1
+ stream-replace-string:
+ specifier: ^2.0.0
+ version: 2.0.0
zod:
specifier: ^3.22.4
version: 3.22.4
@@ -15634,6 +15637,10 @@ packages:
bl: 5.1.0
dev: false
+ /stream-replace-string@2.0.0:
+ resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==}
+ dev: false
+
/stream-transform@2.1.3:
resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==}
dependencies: