File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -194,6 +194,13 @@ export interface ParseSitemapOptions {
194194 * @default true
195195 */
196196 reportNetworkErrors ?: boolean ;
197+ /**
198+ * Optional filter for nested sitemap URLs discovered in sitemap index files.
199+ * Called with the URL of each child sitemap before it is fetched.
200+ * Return `true` to include the sitemap, `false` to skip it.
201+ * If not provided, all nested sitemaps are followed.
202+ */
203+ nestedSitemapFilter ?: ( sitemapUrl : string ) => boolean ;
197204}
198205
199206export async function * parseSitemap < T extends ParseSitemapOptions > (
@@ -209,6 +216,7 @@ export async function* parseSitemap<T extends ParseSitemapOptions>(
209216 sitemapRetries = 3 ,
210217 networkTimeouts,
211218 reportNetworkErrors = true ,
219+ nestedSitemapFilter,
212220 } = options ?? { } ;
213221
214222 const sources = [ ...initialSources ] ;
@@ -340,6 +348,11 @@ export async function* parseSitemap<T extends ParseSitemapOptions>(
340348
341349 for await ( const item of items ) {
342350 if ( item . type === 'sitemapUrl' && ! visitedSitemapUrls . has ( item . url ) ) {
351+ if ( nestedSitemapFilter && ! nestedSitemapFilter ( item . url ) ) {
352+ log . debug ( `Skipping sitemap ${ item . url } due to nestedSitemapFilter.` ) ;
353+ continue ;
354+ }
355+
343356 sources . push ( { type : 'url' , url : item . url , depth : ( source . depth ?? 0 ) + 1 } ) ;
344357 if ( emitNestedSitemaps ) {
345358 yield { loc : item . url , originSitemapUrl : null } as any ;
Original file line number Diff line number Diff line change @@ -294,6 +294,33 @@ describe('Sitemap', () => {
294294 ) ;
295295 } ) ;
296296
297+ it ( 'respects nestedSitemapFilter when following sitemap indexes' , async ( ) => {
298+ const items : SitemapUrl [ ] = [ ] ;
299+
300+ for await ( const item of parseSitemap (
301+ [ { type : 'url' , url : 'http://not-exists.com/sitemap_parent.xml' } ] ,
302+ undefined ,
303+ {
304+ nestedSitemapFilter : ( url ) => ! url . includes ( 'sitemap_child_2' ) ,
305+ } ,
306+ ) ) {
307+ items . push ( item ) ;
308+ }
309+
310+ expect ( items ) . toHaveLength ( 5 ) ;
311+ expect ( items . every ( ( item ) => item . originSitemapUrl === 'http://not-exists.com/sitemap_child.xml' ) ) . toBe ( true ) ;
312+ } ) ;
313+
314+ it ( 'follows all nested sitemaps when nestedSitemapFilter is not provided' , async ( ) => {
315+ const items : SitemapUrl [ ] = [ ] ;
316+
317+ for await ( const item of parseSitemap ( [ { type : 'url' , url : 'http://not-exists.com/sitemap_parent.xml' } ] ) ) {
318+ items . push ( item ) ;
319+ }
320+
321+ expect ( items ) . toHaveLength ( 10 ) ;
322+ } ) ;
323+
297324 it ( 'does not break on invalid xml' , async ( ) => {
298325 const sitemap = await Sitemap . load ( 'http://not-exists.com/not_actual_xml.xml' ) ;
299326 expect ( sitemap . urls ) . toEqual ( [ ] ) ;
You can’t perform that action at this time.
0 commit comments