@@ -366,7 +366,11 @@ export async function build(rootProjectDir?: string, options?: BuildOptions) {
366
366
const renderer = new render . Renderer ( rootConfig , { assetMap, elementGraph} ) ;
367
367
const sitemap = await renderer . getSitemap ( ) ;
368
368
369
- const sitemapXmlItems : string [ ] = [ ] ;
369
+ const sitemapXmlItems : Array < {
370
+ url : string ;
371
+ locale : string ;
372
+ alts : Array < { locale : string ; hreflang : string ; url : string } > ;
373
+ } > = [ ] ;
370
374
if ( rootConfig . sitemap && ! rootConfig . domain ) {
371
375
throw new Error (
372
376
'missing "domain" in root.config.ts, required when using {sitemap: true}'
@@ -396,18 +400,25 @@ export async function build(rootProjectDir?: string, options?: BuildOptions) {
396
400
397
401
// Save the url to sitemap.xml. Ignore error files (e.g. 404.html).
398
402
if ( rootConfig . sitemap && outFilePath . endsWith ( 'index.html' ) ) {
399
- sitemapXmlItems . push ( '<url>' ) ;
400
- sitemapXmlItems . push ( ` <loc>${ domain } ${ urlPath } </loc>` ) ;
403
+ const sitemapXmlItem : {
404
+ url : string ;
405
+ locale : string ;
406
+ alts : Array < { locale : string ; hreflang : string ; url : string } > ;
407
+ } = {
408
+ url : `${ domain } ${ urlPath } ` ,
409
+ locale : sitemapItem . locale ,
410
+ alts : [ ] ,
411
+ } ;
412
+ sitemapXmlItems . push ( sitemapXmlItem ) ;
401
413
if ( sitemapItem . alts ) {
402
414
Object . entries ( sitemapItem . alts ) . forEach ( ( [ altLocale , item ] ) => {
403
- if ( sitemapItem . locale !== altLocale ) {
404
- sitemapXmlItems . push (
405
- ` <xhtml:link rel="alternate" hreflang=" ${ item . hrefLang } " href=" ${ domain } ${ item . urlPath } " />`
406
- ) ;
407
- }
415
+ sitemapXmlItem . alts . push ( {
416
+ url : ` ${ domain } ${ item . urlPath } ` ,
417
+ locale : altLocale ,
418
+ hreflang : item . hrefLang ,
419
+ } ) ;
408
420
} ) ;
409
421
}
410
- sitemapXmlItems . push ( '</url>' ) ;
411
422
}
412
423
413
424
// Render html and save the file to dist/html.
@@ -435,10 +446,28 @@ export async function build(rootProjectDir?: string, options?: BuildOptions) {
435
446
436
447
// Generate sitemap.xml.
437
448
if ( rootConfig . sitemap ) {
449
+ const sitemapXmlBuilder : string [ ] = [ ] ;
450
+ sitemapXmlItems . sort ( ( a , b ) => a . url . localeCompare ( b . url ) ) ;
451
+ sitemapXmlItems . forEach ( ( item ) => {
452
+ sitemapXmlBuilder . push ( '<url>' ) ;
453
+ sitemapXmlBuilder . push ( ` <loc>${ item . url } </loc>` ) ;
454
+ if ( item . alts . length > 0 ) {
455
+ item . alts . sort ( ( a , b ) => a . hreflang . localeCompare ( b . hreflang ) ) ;
456
+ item . alts . forEach ( ( alt ) => {
457
+ if ( item . locale !== alt . locale ) {
458
+ sitemapXmlBuilder . push (
459
+ ` <xhtml:link rel="alternate" hreflang="${ alt . hreflang } " href="${ alt . url } " />`
460
+ ) ;
461
+ }
462
+ } ) ;
463
+ }
464
+ sitemapXmlBuilder . push ( '</url>' ) ;
465
+ } ) ;
466
+
438
467
const sitemapXmlLines = [
439
468
'<?xml version="1.0" encoding="UTF-8"?>' ,
440
469
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">' ,
441
- ...sitemapXmlItems ,
470
+ ...sitemapXmlBuilder ,
442
471
'</urlset>' ,
443
472
] ;
444
473
const sitemapXml = sitemapXmlLines . join ( '\n' ) ;
0 commit comments