How to setup Google Sitemap extension properties in next-sitemap

Are you trying to add Google Sitemap extension properties in your sitemap with next-sitemap? Here is how to do it using a hidden feature of next-sitemap!
4 min read
Barry Boubacar
How to setup Google Sitemap extension properties in next-sitemap

For more than a year, we have been working for local news websites. We needed to ensure that SEO was properly implemented, Google Sitemap extensions in particular. To do that, we chose to use Next.js as framework, and next-sitemap as library in order to generate sitemap(s) and robots.txt for all static/pre-rendered/dynamic/server-side pages.

Google Sitemap extensions require some specific nested fields:

Google News sitemaps

<?xml version="1.0" encoding="UTF-8"?>
<urlset
	xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
	xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
	<url>
		<loc>http://www.example.org/business/article55.html</loc>
		<news:news>
			<news:publication>
				<news:name>The Example Times</news:name>
				<news:language>en</news:language>
			</news:publication>
			<news:publication_date>2008-12-23</news:publication_date>
			<news:title>Companies A, B in Merger Talks</news:title>
		</news:news>
	</url>
</urlset>

Video sitemaps

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
   <url>
     <loc>http://www.example.com/videos/some_video_landing_page.html</loc>
     <video:video>
       <video:thumbnail_loc>http://www.example.com/thumbs/123.jpg</video:thumbnail_loc>
       <video:title>Grilling steaks for summer</video:title>
       <video:description>Alkis shows you how to get perfectly done steaks every
         time</video:description>
       <video:content_loc>
          http://streamserver.example.com/video123.mp4</video:content_loc>
       <video:player_loc>
         http://www.example.com/videoplayer.php?video=123</video:player_loc>
       <video:duration>600</video:duration>
       <video:expiration_date>2021-11-05T19:20:30+08:00</video:expiration_date>
       <video:rating>4.2</video:rating>
       <video:view_count>12345</video:view_count>
       <video:publication_date>2007-11-05T19:20:30+08:00</video:publication_date>
       <video:family_friendly>yes</video:family_friendly>
       <video:restriction relationship="allow">IE GB US CA</video:restriction>
       <video:price currency="EUR">1.99</video:price>
       <video:requires_subscription>yes</video:requires_subscription>
       <video:uploader
         info="http://www.example.com/users/grillymcgrillerson">GrillyMcGrillerson
       </video:uploader>
       <video:live>no</video:live>
     </video:video>
   </url>
</urlset>

Image sitemaps

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
  <url>
    <loc>http://example.com/sample1.html</loc>
    <image:image>
      <image:loc>http://example.com/image.jpg</image:loc>
    </image:image>
    <image:image>
      <image:loc>http://example.com/photo.jpg</image:loc>
    </image:image>
  </url>
  <url>
    <loc>http://example.com/sample2.html</loc>
    <image:image>
      <image:loc>http://example.com/picture.jpg</image:loc>
    </image:image>
  </url>
</urlset>

At the moment, next-sitemap configuration does not support these nested fields in `ISitemapField`  but it provides a "hidden feature".

You can provide a key-value pair in your next-sitemap config object where the key  is the XML tag and the value is the content of this XML tag.  

If you provide a key different from alternateRefs, it will be automatically pushed into the final XML string (see screenshot next-sitemap source code)

next-sitemap - buildSitemapXml.ts#L12

Our example will look like this:

{
        loc: `http://www.example.org/business/article55.html`,
        lastmod: new Date().toISOString(),
        changefreq: 'hourly',
        // Support Google News sitemaps
        'news:news': `
          <news:publication>
            <news:name>The Example Times</news:name>
            <news:language>en</news:language>
          </news:publication>
          <news:publication_date>2008-12-23</news:publication_date>
          <news:title>Companies A, B in Merger Talks</news:title>
        `,
        // Support Video sitemaps
        'video:video': `
          <video:thumbnail_loc>http://www.example.com/thumbs/123.jpg</video:thumbnail_loc>
         <video:title>Grilling steaks for summer</video:title>
         <video:description>Alkis shows you how to get perfectly done steaks every
           time</video:description>
         <video:content_loc>
            http://streamserver.example.com/video123.mp4</video:content_loc>
         <video:player_loc>
           http://www.example.com/videoplayer.php?video=123</video:player_loc>
         <video:duration>600</video:duration>
         <video:expiration_date>2021-11-05T19:20:30+08:00</video:expiration_date>
         <video:rating>4.2</video:rating>
         <video:view_count>12345</video:view_count>
         <video:publication_date>2007-11-05T19:20:30+08:00</video:publication_date>
         <video:family_friendly>yes</video:family_friendly>
         <video:restriction relationship="allow">IE GB US CA</video:restriction>
         <video:price currency="EUR">1.99</video:price>
         <video:requires_subscription>yes</video:requires_subscription>
         <video:uploader
           info="http://www.example.com/users/grillymcgrillerson">GrillyMcGrillerson
         </video:uploader>
         <video:live>no</video:live>
        `,
        // Support Image sitemaps
        'image:image': `
          <image:loc>
           http://example.com/image.jpg
          </image:loc>
        `,
      } as ISitemapField

Conclusion

Overall, I think it's great that we have this option to easily add nested fields. However, because Google Sitemap is a kind of standard,I'd love to see it added as a configuration option, especially because of typescript.

Of course, if you have any questions, feel free to reach out!