index with multiple categorized sitemaps
tasiotas opened this issue · 5 comments
Hi,
I would like to split sitemaps per category and have them all referenced in sitemap-index.xml.
It does not seem to be trivial given existing examples. Does anyone have done similar setup?
This is what I would like to achieve, currently I can only write to single sitemap stream. Following SitemapAndIndexStream
example.
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://website.com/sitemap-blog-0.xml</loc>
</sitemap>
<sitemap>
<loc>https://website.com/sitemap-blog-1.xml</loc>
</sitemap>
<sitemap>
<loc>https://website.com/sitemap-shop-0.xml</loc>
</sitemap>
<sitemap>
<loc>https://website.com/sitemap-shop-1.xml</loc>
</sitemap>
</sitemapindex>
perhaps its out of scope of this project. I managed to split it with simpleSitemapAndIndex
and lots of additional code
@tasiotas Can you please show me how did you manage to create different multiple sitemaps with indexing.
sorry, in the end I dropped sitemap.js lib and went full with custom code writing my own XMLs.
I dont have a code at hand where I had it working with simpleSitemapAndIndex
. I believe I was calling it multiple times, and then moving/renaming output file. I had to generate indexes by hand anyway...
@tasiotas Thanks for the quick response.
Even I considered doing custom code to generate XML as I want as the package is less supportive for creating multiple sitemaps at once and index it in sitemap.xml.
It's a little late to be here but here is how I managed it.
import fs from "node:fs";
import { type SitemapItemLoose, SitemapAndIndexStream, SitemapStream, SitemapIndexStream } from "sitemap";
const hostname = "https://...";
export default class SitemapApplication {
generateSitemap() {
const blogs= []; /* get items from somewhere */
const books= []; /* get items from somewhere */
const movies= []; /* get items from somewhere */
this.createSitemapCategory(blogs, "blog", true);
this.createSitemapCategory(books, "books", true);
this.createSitemapCategory(movies, "movies", true);
this.createIndexStream(["blog", "books", "movies"]);
}
private createIndexStream(categories: string[]) {
const indexStream = new SitemapIndexStream();
categories.forEach(category => indexStream.write({ url: `${hostname}/sitemap_${category}.xml` }));
indexStream.pipe(fs.createWriteStream("sitemap_index.xml"));
indexStream.end();
}
private createSitemapCategory(data: SitemapItemLoose[], name: string, singleFile = false) {
const stream = new SitemapAndIndexStream({
getSitemapStream: index => {
const sitemapStream = new SitemapStream({
hostname: hostname
});
const filePath = singleFile && index === 0 ? `sitemap_${name}.xml` : `sitemap_${name}-${index}.xml`;
const ws = sitemapStream
.pipe(fs.createWriteStream(filePath));
return [new URL(filePath, hostname).toString(), sitemapStream, ws];
}
});
data.forEach(item => stream.write(item));
stream.end();
}
}