sitemap-builder.js 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /**
  2. * Builder class to generate xml and robots.txt
  3. * Returns only string values
  4. */
  5. export class SitemapBuilder {
  6. /**
  7. * Create XML Template
  8. * @param content
  9. * @returns
  10. */
  11. withXMLTemplate(content) {
  12. return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">\n${content}</urlset>`;
  13. }
  14. /**
  15. * Generates sitemap-index.xml
  16. * @param allSitemaps
  17. * @returns
  18. */
  19. buildSitemapIndexXml(allSitemaps) {
  20. return [
  21. '<?xml version="1.0" encoding="UTF-8"?>',
  22. '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
  23. ...(allSitemaps?.map((x) => `<sitemap><loc>${x}</loc></sitemap>`) ?? []),
  24. '</sitemapindex>',
  25. ].join('\n');
  26. }
  27. /**
  28. * Normalize sitemap field keys to stay consistent with <xsd:sequence> order
  29. * @link https://www.w3schools.com/xml/el_sequence.asp
  30. * @link https://github.com/iamvishnusankar/next-sitemap/issues/345
  31. * @param x
  32. * @returns
  33. */
  34. normalizeSitemapField(x) {
  35. const { loc, lastmod, changefreq, priority, ...restProps } = x;
  36. // Return keys in following order
  37. return {
  38. loc,
  39. lastmod,
  40. changefreq,
  41. priority,
  42. ...restProps,
  43. };
  44. }
  45. /**
  46. * Generates sitemap.xml
  47. * @param fields
  48. * @returns
  49. */
  50. buildSitemapXml(fields) {
  51. const content = fields
  52. .map((x) => {
  53. // Normalize sitemap field keys to stay consistent with <xsd:sequence> order
  54. const field = this.normalizeSitemapField(x);
  55. // Field array to keep track of properties
  56. const fieldArr = [];
  57. // Iterate all object keys and key value pair to field-set
  58. for (const key of Object.keys(field)) {
  59. // Skip reserved keys
  60. if (['trailingSlash'].includes(key)) {
  61. continue;
  62. }
  63. if (field[key]) {
  64. if (key !== 'alternateRefs') {
  65. fieldArr.push(`<${key}>${field[key]}</${key}>`);
  66. }
  67. else {
  68. const altRefField = this.buildAlternateRefsXml(field.alternateRefs);
  69. fieldArr.push(altRefField);
  70. }
  71. }
  72. }
  73. // Append previous value and return
  74. return `<url>${fieldArr.join('')}</url>\n`;
  75. })
  76. .join('');
  77. return this.withXMLTemplate(content);
  78. }
  79. /**
  80. * Generate alternate refs.xml
  81. * @param alternateRefs
  82. * @returns
  83. */
  84. buildAlternateRefsXml(alternateRefs = []) {
  85. return alternateRefs
  86. .map((alternateRef) => {
  87. return `<xhtml:link rel="alternate" hreflang="${alternateRef.hreflang}" href="${alternateRef.href}"/>`;
  88. })
  89. .join('');
  90. }
  91. }