{"id":633,"date":"2022-09-09T17:24:29","date_gmt":"2022-09-09T23:24:29","guid":{"rendered":"https:\/\/developers.wpengine.com\/blog\/?p=633"},"modified":"2023-04-26T11:24:15","modified_gmt":"2023-04-26T17:24:15","slug":"sitemaps-headless-wordpress-next-js","status":"publish","type":"post","link":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/","title":{"rendered":"Sitemaps in Headless WordPress with Next.js"},"content":{"rendered":"\n<p>In this tutorial, you will learn how to create sitemaps in Headless WordPress using Next.js and the WP Sitemap Rest API plugin.  (Just a note, if you need a foundational understanding of Next.js, please follow this <a href=\"https:\/\/wpengine.com\/builders\/crash-course-build-a-simple-headless-wordpress-app-with-next-js-wpgraphql\">tutorial<\/a> by my main man Jeff Everhart.<\/p>\n\n\n\n<p>Previously, I wrote about what Sitemaps are and the benefits of them in this article you can reference <a href=\"https:\/\/wpengine.com\/builders\/sitemaps-in-headless-wordpress-with-faust-js\">here<\/a>.  In the context of this blog post, we will jump right into creating the sitemaps.  By the end of this tutorial you will be able to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create a Sitemap in Next.js that dynamically pulls your URLs from WordPress<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Add your Next.js pages and paths on your Sitemap including dynamic routes<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Setup your WordPress Site<\/h2>\n\n\n\n<p>The first thing we are going to do is configure your WordPress site so that we have access to the particular endpoints for our Sitemaps.  We are going to use the <a href=\"https:\/\/github.com\/dipankarmaikap\/wp-sitemap-rest-api\">WP Sitemap Rest API plugin<\/a>.  Download the plugin from the repo via zip file.  Next, In WP Admin, go to the <code>Plugins &gt; Add Plugins<\/code> option at the top right and upload the plugin.<\/p>\n\n\n\n<p>Once you install that plugin, you expose these 4 endpoints to your <code>REST API<\/code> in WordPress:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>\/wp-json\/sitemap\/v1\/totalpages\n<\/span><\/span><span class='shcb-loc'><span>\/wp-json\/sitemap\/v1\/author?pageNo=1&amp;perPage=1000\n<\/span><\/span><span class='shcb-loc'><span>\/wp-json\/sitemap\/v1\/taxonomy?pageNo=1&amp;perPage=1000&amp;taxonomyType=category or tag\n<\/span><\/span><span class='shcb-loc'><span>\/wp-json\/sitemap\/v1\/posts?pageNo=1&amp;perPage=1000&amp;postType=post or page\n<\/span><\/span><\/code><\/span><\/pre>\n\n\n<p>Easily, with this plugin, if you visit &#8220;<code>your.wordpresssite.com<\/code>&#8221; plus appending any of the 4 endpoints, you will get an object back of what those paths reflect.  An example of my demo site with the first endpoint added:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-05-at-5.17.12-PM-1024x309.png\" alt=\"\" class=\"wp-image-635\"\/><\/figure>\n\n\n\n<p>Easy Peasy, now on to the Next.js frontend. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Install Dependencies <\/h2>\n\n\n\n<p>Before we go into the code, we need to install a dependency we will use in this tutorial within our Next.js project called <a href=\"https:\/\/www.npmjs.com\/package\/axios\">axios<\/a>.  Axios will give us some helper functionality to make <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/XMLHttpRequest\">XMLHttpRequests<\/a> from our Next.js front-end.   To do this, run <code>npm i axios<\/code> in your terminal.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Environment Variables<\/h2>\n\n\n\n<p>There are a couple of endpoints we will have to set up as environment variables in our project before we create the functions needed.<\/p>\n\n\n\n<p>In the root of your project, create a <code>.env.local<\/code> file. In this file, add your endpoints and how many items per sitemap you would want. Note that on the frontend URL, because I am using a development environment on my local machine, I am using the Next.js default of localhost with port 3000.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span>NEXT_PUBLIC_WORDPRESS_API_URL=https:<span class=\"hljs-comment\">\/\/yourwordpresssite.com<\/span>\n<\/span><\/span><span class='shcb-loc'><span>NEXT_PUBLIC_FRONTEND_URL=http:<span class=\"hljs-comment\">\/\/localhost:3000<\/span>\n<\/span><\/span><span class='shcb-loc'><span>NEXT_PUBLIC_ITEM_PER_SITEMAP=<span class=\"hljs-number\">50<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Now that we have added our environment variables in the properly named file, let&#8217;s allow our project access to them via the <code>process.env <\/code>object.<\/p>\n\n\n\n<p>In the root of your project, create a <code>utils<\/code> folder.  In the utils folder, create a file called <code>variables.js<\/code>. In this file, add this code block:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> wordpressUrl = process.env.NEXT_PUBLIC_WORDPRESS_URL;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">let<\/span> frontendUrl = process.env.NEXT_PUBLIC_FRONTEND_URL;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">let<\/span> sitemapPerPage = process.env.NEXT_PUBLIC_ITEM_PER_SITEMAP || <span class=\"hljs-number\">50<\/span>; <span class=\"hljs-comment\">\/\/1000<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The variables we are naming above are needed so that Next.js can access those endpoints from our <code>.env.local<\/code> with the <code>process.env<\/code> object.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Next.js sitemap functions<\/h2>\n\n\n\n<p>We are going to need a few functions in order to dynamically grab the total amount of WordPress URLs to make them available to your sitemap index page and show them on the browser as well as showing our Next.js front-end URL&#8217;s.<\/p>\n\n\n\n<p>The first step is to create a folder called <code>lib<\/code> in the root of the project.  In the new <code>lib<\/code> folder, create a file called <code>getTotalCounts.js<\/code> and add this code block:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> axios <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"axios\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { wordpressUrl } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/utils\/variables\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getTotalCounts<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> res = <span class=\"hljs-keyword\">await<\/span> axios.get(<span class=\"hljs-string\">`<span class=\"hljs-subst\">${wordpressUrl}<\/span>\/wp-json\/sitemap\/v1\/totalpages`<\/span>);\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> data = <span class=\"hljs-keyword\">await<\/span> res.data;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">if<\/span> (!data) <span class=\"hljs-keyword\">return<\/span> &#91;];\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> propertyNames = <span class=\"hljs-built_in\">Object<\/span>.keys(data);\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> excludeItems = &#91;<span class=\"hljs-string\">\"user\"<\/span>];\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-comment\">\/\/if you want to remove any item from sitemap, add it to excludeItems array<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> totalArray = propertyNames\n<\/span><\/span><span class='shcb-loc'><span>    .filter(<span class=\"hljs-function\">(<span class=\"hljs-params\">name<\/span>) =&gt;<\/span> !excludeItems.includes(name))\n<\/span><\/span><span class='shcb-loc'><span>    .map(<span class=\"hljs-function\">(<span class=\"hljs-params\">name<\/span>) =&gt;<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-keyword\">return<\/span> { name, <span class=\"hljs-attr\">total<\/span>: data&#91;name] };\n<\/span><\/span><span class='shcb-loc'><span>    });\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> totalArray;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This file is a fetch function that is grabbing the total pages from your WordPress site and returning that data in an array.  If you want to exclude any data from your sitemap you can add it to the <code>excludeItems<\/code>  array as commented.<\/p>\n\n\n\n<p>The next thing we need to create is a way to get the sitemap pages and return them for the specific type. <\/p>\n\n\n\n<p>Back in our <code>utils<\/code> folder, create a file called <code>getSitemapPages.js<\/code> and add this code block:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { frontendUrl, sitemapPerPage } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/variables\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getSitemapPages<\/span>(<span class=\"hljs-params\">item<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> items = &#91;];\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">let<\/span> i = <span class=\"hljs-number\">1<\/span>; i &lt;= <span class=\"hljs-built_in\">Math<\/span>.ceil(item.total \/ sitemapPerPage); i++) {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">let<\/span> url = <span class=\"hljs-string\">`<span class=\"hljs-subst\">${frontendUrl}<\/span>\/sitemap\/<span class=\"hljs-subst\">${item.name}<\/span>_sitemap<span class=\"hljs-subst\">${i}<\/span>.xml`<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    items.push(\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-string\">` <\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">        &lt;sitemap&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">           &lt;loc&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">              <span class=\"hljs-subst\">${url}<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">          &lt;\/loc&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      &lt;\/sitemap&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      `<\/span>\n<\/span><\/span><span class='shcb-loc'><span>    );\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> items.join(<span class=\"hljs-string\">\"\"<\/span>);\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This file is importing the variables we declared in our <code>variables.js<\/code> file.  Then, it exports a function by default that is passing in the item from the total counts function we created.  Once these are passed in, the front-end URL is appended with the item name and the XML path.  Then we join these with the XML tags with the slug from WordPress. <\/p>\n\n\n\n<p>We now have the necessary functions in place to generate our sitemap pages and the total number of them.  The next step is to create a sitemap index page.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Sitemap Index Page<\/h2>\n\n\n\n<p>We are going to take advantage of<a href=\"https:\/\/nextjs.org\/docs\/basic-features\/pages\"> Next.js<\/a> and its page-based file routing.&nbsp; This means that any file I add to the pages directory in my project will correspond automatically to a route that is available.&nbsp;<\/p>\n\n\n\n<p>Create a file in the <code>pages<\/code> directory of your project called <code>sitemap.xml.js<\/code> and add this code block:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> getSitemapPages <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/utils\/getSitemapPages\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> getTotalCounts <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/lib\/getTotalCounts\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">SitemapIndexPage<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">null<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getServerSideProps<\/span>(<span class=\"hljs-params\">{ res }<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> details = <span class=\"hljs-keyword\">await<\/span> getTotalCounts();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> sitemapIndex = <span class=\"hljs-string\">`&lt;?xml version='1.0' encoding='UTF-8'?&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  &lt;sitemapindex xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">           xsi:schemaLocation=\"http:\/\/www.sitemaps.org\/schemas\/sitemap\/0.9 http:\/\/www.sitemaps.org\/schemas\/sitemap\/0.9\/siteindex.xsd\"<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">           xmlns=\"http:\/\/www.sitemaps.org\/schemas\/sitemap\/0.9\"&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">     <span class=\"hljs-subst\">${details.map((item) =&gt; getSitemapPages(item)).join(<span class=\"hljs-string\">\"\"<\/span>)}<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">  &lt;\/sitemapindex&gt;`<\/span>;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  res.setHeader(<span class=\"hljs-string\">\"Content-Type\"<\/span>, <span class=\"hljs-string\">\"text\/xml; charset=utf-8\"<\/span>);<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  res.setHeader(<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    <span class=\"hljs-string\">\"Cache-Control\"<\/span>,<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    <span class=\"hljs-string\">\"public, s-maxage=600, stale-while-revalidate=600\"<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  );<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  res.write(sitemapIndex);<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  res.end();<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  <span class=\"hljs-keyword\">return<\/span> { <span class=\"hljs-attr\">props<\/span>: {} };<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">}<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The first thing to notice at the top of the file is the importing of the two functions we just created to generate the WordPress page types and the total counts.  Then we have this page as a default function that will utilize server-side rendering since we want this page to be dynamic on every request so the sitemap is up to date.  <\/p>\n\n\n\n<p>Next, I copied a sitemap example and formatted it so that the XML tags and links show up on the browser with the response header set and the page write response set to load and end with the props returned.   <\/p>\n\n\n\n<p>Let&#8217;s get stoked now and see what this looks like on the browser.  Go to your terminal and run <code>npm run dev<\/code>.  You should see this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-07-at-8.15.03-AM-1024x516.png\" alt=\"\" class=\"wp-image-639\"\/><\/figure>\n\n\n\n<p>Awesome!! We now have a dynamic sitemap in a headless WordPress setup.  The next step is to add the ability to grab the URL of the sitemap path and have that route to its detail page.  <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dynamic Sitemap Page Routes<\/h2>\n\n\n\n<p>We need a couple of things to make the dynamic page routes work for our sitemap.  First, we need a way to generate the sitemap paths to their detail page.  <\/p>\n\n\n\n<p>Go back to the <code>utils<\/code> folder we created earlier.  In this folder, create a <code>generateSitemapPaths.js <\/code>file and add this code block:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> { frontendUrl } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\".\/variables\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">generateSitemapPaths<\/span>(<span class=\"hljs-params\">array<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> items = array.map(\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-function\">(<span class=\"hljs-params\">item<\/span>) =&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-string\">`<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">            &lt;url&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">                &lt;loc&gt;<span class=\"hljs-subst\">${frontendUrl + item?.url}<\/span>&lt;\/loc&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">                <span class=\"hljs-subst\">${<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">                  item?.post_modified_date<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">                    ? <span class=\"hljs-string\">`&lt;lastmod&gt;<span class=\"hljs-subst\">${<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\"><span class=\"hljs-subst\">                        <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>(item?.post_modified_date)<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\"><span class=\"hljs-subst\">                          .toISOString()<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\"><span class=\"hljs-subst\">                          .split(<span class=\"hljs-string\">\"T\"<\/span>)&#91;<span class=\"hljs-number\">0<\/span>]<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\"><span class=\"hljs-subst\">                      }<\/span>&lt;\/lastmod&gt;`<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\">                    : <span class=\"hljs-string\">\"\"<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\">                }<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">            &lt;\/url&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">            `<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  );<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  <span class=\"hljs-keyword\">return<\/span> items.join(<span class=\"hljs-string\">\"\"<\/span>);<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">}<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This file imports our front-end URL variable and then exports a default function that passes in an array.  The items variable is mapped which then returns a single item.  Then we have XML tags that dynamically grab the appropriate item and concatenate that to your frontend URL, as well as the date the page was last modified.  Now that we have the function needed, let&#8217;s create the dynamic route page.<\/p>\n\n\n\n<p>Next.js makes it easy to create a dynamic file if you have a parameter like a <code>slug<\/code> that changes upon request.  The naming convention for this is the bracket syntax.  Create a folder in the pages directory called <code>sitemap<\/code>.  In this folder, create a file called <code>[slug].js<\/code>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-07-at-8.29.35-AM-1024x626.png\" alt=\"\" class=\"wp-image-640\"\/><\/figure>\n\n\n\n<p>In the <code>[slug].js<\/code> file, add this code block:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> getSitemapPageUrls <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/..\/lib\/getSitemapPageUrls\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> getTotalCounts <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/..\/lib\/getTotalCounts\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> generateSitemapPaths <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/..\/utils\/generateSitemapPaths\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">SitemapTagPage<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">null<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getServerSideProps<\/span>(<span class=\"hljs-params\">{ res, params: { slug } }<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> isXml = slug.endsWith(<span class=\"hljs-string\">\".xml\"<\/span>);\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">if<\/span> (!isXml) {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">return<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">notFound<\/span>: <span class=\"hljs-literal\">true<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    };\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> slugArray = slug.replace(<span class=\"hljs-string\">\".xml\"<\/span>, <span class=\"hljs-string\">\"\"<\/span>).split(<span class=\"hljs-string\">\"_\"<\/span>);\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> type = slugArray&#91;<span class=\"hljs-number\">0<\/span>];\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> pageNo = slugArray&#91;<span class=\"hljs-number\">1<\/span>]?.match(<span class=\"hljs-regexp\">\/(\\d+)\/<\/span>)&#91;<span class=\"hljs-number\">0<\/span>] ?? <span class=\"hljs-literal\">null<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> page = pageNo ? <span class=\"hljs-built_in\">parseInt<\/span>(pageNo) : <span class=\"hljs-literal\">null<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> possibleTypes = <span class=\"hljs-keyword\">await<\/span> getTotalCounts();\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">if<\/span> (!possibleTypes.some(<span class=\"hljs-function\">(<span class=\"hljs-params\">e<\/span>) =&gt;<\/span> e.name === type)) {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">return<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">notFound<\/span>: <span class=\"hljs-literal\">true<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    };\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> pageUrls = <span class=\"hljs-keyword\">await<\/span> getSitemapPageUrls({ type, page });\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">if<\/span> (!pageUrls?.length) {\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-keyword\">return<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-attr\">notFound<\/span>: <span class=\"hljs-literal\">true<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    };\n<\/span><\/span><span class='shcb-loc'><span>  }\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> sitemap = <span class=\"hljs-string\">`&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  &lt;urlset xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  xsi:schemaLocation=\"http:\/\/www.sitemaps.org\/schemas\/sitemap\/0.9 http:\/\/www.sitemaps.org\/schemas\/sitemap\/0.9\/sitemap.xsd\"<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  xmlns=\"http:\/\/www.sitemaps.org\/schemas\/sitemap\/0.9\"&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    <span class=\"hljs-subst\">${generateSitemapPaths(pageUrls)}<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  &lt;\/urlset&gt;`<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>  res.setHeader(<span class=\"hljs-string\">\"Content-Type\"<\/span>, <span class=\"hljs-string\">\"text\/xml; charset=utf-8\"<\/span>);\n<\/span><\/span><span class='shcb-loc'><span>  res.setHeader(\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">\"Cache-Control\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>    <span class=\"hljs-string\">\"public, s-maxage=600, stale-while-revalidate=600\"<\/span>\n<\/span><\/span><span class='shcb-loc'><span>  );\n<\/span><\/span><span class='shcb-loc'><span>  res.write(sitemap);\n<\/span><\/span><span class='shcb-loc'><span>  res.end();\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> { <span class=\"hljs-attr\">props<\/span>: {} };\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>There is quite a bit of code in this file.  Essentially, what is happening in this file is that we are importing all of our functions at the top that we need access to for the sitemap dynamic paths.<\/p>\n\n\n\n<p>Next, a default function is exported, calling it <code>SitemapTagPage<\/code>.  We return null, then have an async function to getServerSideProps as we want this function to be server-side rendered as well on every request.  Then in the response object, we pass in the params which is the slug in this case.<\/p>\n\n\n\n<p>Our variable <code>isXML<\/code> is equal to the slug and the appended XML path ending.  If this a not an <code>xml slug<\/code> and path we return it to not be found.<\/p>\n\n\n\n<p>In the middle of the file, we declare numerous variables that we name as we need to set the array of slugs, the type, the page number using regex which extracts the number from the string, and the possible types and the total counts of those types. <\/p>\n\n\n\n<p>Lastly, we validate this to see if it properly is aligned with our sitemap index page, otherwise, we throw a <code>404<\/code>.  Once that is done, we have our <code>XML<\/code> tags formatted and the appropriate responses.<\/p>\n\n\n\n<p>Let&#8217;s try this now and see if this works in the browser.  Go back to the terminal and run <code>npm run dev<\/code>.  Once the sitemap index page shows on the browser, grab any <code>URL<\/code> on the sitemap and put it in the search bar:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-07-at-9.53.31-AM-1024x504.png\" alt=\"\" class=\"wp-image-641\"\/><\/figure>\n\n\n\n<p> I chose to grab my post page URL at <code>sitemap\/post_sitemap1.xml<\/code>.  I followed that link in the search bar and got the post sitemap details! Stoked!! \ud83c\udf89<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Next.js Pages<\/h2>\n\n\n\n<p>Finally, we need to account for our Next.js pages on our front-end.  In order to do this, let&#8217;s go to our pages directory and add a file called <code>sitemapnextjs.xml.js<\/code>.  In this file, add this code block:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> React <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"react\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> * <span class=\"hljs-keyword\">as<\/span> fs <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"fs\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">const<\/span> Sitemap = <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">null<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>};\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> getServerSideProps = <span class=\"hljs-keyword\">async<\/span> ({ res }) =&gt; {\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> BASE_URL = <span class=\"hljs-string\">\"http:\/\/localhost:3000\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> staticPaths = fs\n<\/span><\/span><span class='shcb-loc'><span>    .readdirSync(<span class=\"hljs-string\">\"pages\"<\/span>)\n<\/span><\/span><span class='shcb-loc'><span>    .filter(<span class=\"hljs-function\">(<span class=\"hljs-params\">staticPage<\/span>) =&gt;<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-keyword\">return<\/span> !&#91;\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-string\">\"api\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-string\">\"about\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-string\">\"_app.js\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-string\">\"_document.js\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-string\">\"404.js\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>        <span class=\"hljs-string\">\"sitemap.xml.js\"<\/span>,\n<\/span><\/span><span class='shcb-loc'><span>      ].includes(staticPage);\n<\/span><\/span><span class='shcb-loc'><span>    })\n<\/span><\/span><span class='shcb-loc'><span>    .map(<span class=\"hljs-function\">(<span class=\"hljs-params\">staticPagePath<\/span>) =&gt;<\/span> {\n<\/span><\/span><span class='shcb-loc'><span>      <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">`<span class=\"hljs-subst\">${BASE_URL}<\/span>\/<span class=\"hljs-subst\">${staticPagePath}<\/span>`<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>    });\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> dynamicPaths = &#91;<span class=\"hljs-string\">`<span class=\"hljs-subst\">${BASE_URL}<\/span>\/name\/1`<\/span>, <span class=\"hljs-string\">`<span class=\"hljs-subst\">${BASE_URL}<\/span>\/name\/2`<\/span>];\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> allPaths = &#91;...staticPaths, ...dynamicPaths];\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> sitemap = <span class=\"hljs-string\">`&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    &lt;urlset xmlns=\"http:\/\/www.sitemaps.org\/schemas\/sitemap\/0.9\"&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">      <span class=\"hljs-subst\">${allPaths<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">        .map((url) =&gt; {<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">          <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">`<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\">            &lt;url&gt;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\">              &lt;loc&gt;<span class=\"hljs-subst\">${url}<\/span>&lt;\/loc&gt;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\">              &lt;lastmod&gt;<span class=\"hljs-subst\">${<span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>().toISOString()}<\/span>&lt;\/lastmod&gt;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\"><span class=\"hljs-subst\">              &lt;changefreq&gt;monthly&lt;\/changefreq&gt;<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\"><span class=\"hljs-subst\">              &lt;priority&gt;1.0&lt;\/priority&gt;<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\"><span class=\"hljs-subst\">            &lt;\/url&gt;<\/span><\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\"><span class=\"hljs-subst\">          `<\/span>;<\/span><\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\"><span class=\"hljs-string\">        }<\/span>)<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">        .join(\"\")}<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">    &lt;\/urlset&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">  `<\/span>;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  res.setHeader(<span class=\"hljs-string\">\"Content-Type\"<\/span>, <span class=\"hljs-string\">\"text\/xml\"<\/span>);<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  res.write(sitemap);<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  res.end();<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  <span class=\"hljs-keyword\">return<\/span> {<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    <span class=\"hljs-attr\">props<\/span>: {},<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  };<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">};<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> Sitemap;<\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>At the top of the file, we are importing React, and fs to access local storage.  Next, we return null as we want this to not render or return anything in the component.  Instead, we will use the <code>getServerSideProps<\/code> function, export it as a const, then pass in the response object, just like we did in the sitemap index page to server-side render for fresh, up-to-date sitemap data.  <\/p>\n\n\n\n<p>Then we declare our base URL variable, in this case, I am using the dev server off <code>localhost:3000<\/code>.<\/p>\n\n\n\n<p>Once we set the <code>fs<\/code> to our static paths, we enable a way within the object to filter through our static pages in Next.js within an array and input which ones we do not want on the sitemap.  I just added the default pages Next.js comes with as an example.  <\/p>\n\n\n\n<p>The next step is to account for the dynamic paths that you have in Next.js, apart from WordPress.  We set a const for our dynamic paths and make it equal to an array where we get our base URL and our hard coded path.  (I just named it &#8220;name&#8221; but you can name it in relation to whatever your dynamic route file is)<\/p>\n\n\n\n<p>The last things we need to do are to set the const for all our paths and iterate through them with the spread operator and expand all of them in an array.<\/p>\n\n\n\n<p>Finally, we generate the sitemap in <code>XML<\/code> format with the appropriate response headers returning our props. Jamstoked!!  We now have all the paths and the URLS in our Next.js front-end!!! \ud83d\udca5<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Combining Next.js pages and WordPress pages in your sitemap index page<\/h2>\n\n\n\n<p>All that is left is adding our Next.js pages to our sitemap index with our WordPress pages.  Go back to the sitemap.xml.js file and add this code block:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-code-table shcb-line-numbers\"><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> getSitemapPages <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/utils\/getSitemapPages\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">import<\/span> getTotalCounts <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">\"..\/lib\/getTotalCounts\"<\/span>;\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">SitemapIndexPage<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">null<\/span>;\n<\/span><\/span><span class='shcb-loc'><span>}\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">async<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">getServerSideProps<\/span>(<span class=\"hljs-params\">{ res }<\/span>) <\/span>{\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">const<\/span> details = <span class=\"hljs-keyword\">await<\/span> getTotalCounts();\n<\/span><\/span><span class='shcb-loc'><span>\n<\/span><\/span><span class='shcb-loc'><span>  <span class=\"hljs-keyword\">let<\/span> sitemapIndex = <span class=\"hljs-string\">`&lt;?xml version='1.0' encoding='UTF-8'?&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  &lt;sitemapindex xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">           xsi:schemaLocation=\"http:\/\/www.sitemaps.org\/schemas\/sitemap\/0.9 http:\/\/www.sitemaps.org\/schemas\/sitemap\/0.9\/siteindex.xsd\"<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">           xmlns=\"http:\/\/www.sitemaps.org\/schemas\/sitemap\/0.9\"&gt;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">     <span class=\"hljs-subst\">${details.map((item) =&gt; getSitemapPages(item)).join(<span class=\"hljs-string\">\"\"<\/span>)}<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">     &lt;sitemap&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">     &lt;loc&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">        http:\/\/localhost:3000\/sitemapnextjs.xml<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">    &lt;\/loc&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">&lt;\/sitemap&gt;<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><span class=\"hljs-subst\">  &lt;\/sitemapindex&gt;`<\/span>;<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  res.setHeader(<span class=\"hljs-string\">\"Content-Type\"<\/span>, <span class=\"hljs-string\">\"text\/xml; charset=utf-8\"<\/span>);<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  res.setHeader(<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    <span class=\"hljs-string\">\"Cache-Control\"<\/span>,<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">    <span class=\"hljs-string\">\"public, s-maxage=600, stale-while-revalidate=600\"<\/span><\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  );<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  res.write(sitemapIndex);<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  res.end();<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">  <span class=\"hljs-keyword\">return<\/span> { <span class=\"hljs-attr\">props<\/span>: {} };<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\">}<\/span>\n<\/span><\/span><span class='shcb-loc'><span><span class=\"hljs-string\"><\/span>\n<\/span><\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>The one difference in this file is the URL we added <code>http:\/\/localhost:3000\/sitemapnextjs.xml<\/code> in our XML element <code>&lt;loc&gt;&lt;\/loc&gt;<\/code>.  This will allow us to show the Next.js pages on our sitemap index.  <\/p>\n\n\n\n<p>Let&#8217;s see this in action in the browser.  Go back to terminal and run <code>npm run dev<\/code>.  You should see this in the browser:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-07-at-11.59.55-AM-1024x428.png\" alt=\"\" class=\"wp-image-642\"\/><\/figure>\n\n\n\n<p>We now have our sitemap for Next.js pages on our index.  Let&#8217;s see what all the details of our pages are in Next.js when we follow that URL:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-07-at-12.01.22-PM-1024x525.png\" alt=\"\" class=\"wp-image-643\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Done!! Jamstoked! \ud83c\udf89<\/h2>\n\n\n\n<p>We are finished with this walk-through tutorial! Jamstoke! With this tutorial, we hope you take away the ability to understand the importance of sitemaps and the value of utilizing them to inform search engines of your site&#8217;s page and path layout.  <\/p>\n\n\n\n<p>This is just one way of approaching sitemaps in headless WordPress. I would love to hear your thoughts and your own approaches and builds. Hit me up in our&nbsp;<code><a href=\"https:\/\/discord.com\/invite\/J2khkF9XYK\" target=\"_blank\" rel=\"noreferrer noopener\">Discord<\/a><\/code>!<\/p>\n\n\n\n<p>Here is the demo once again so you can follow along, make it your own and add on to it if you like on my&nbsp;<a href=\"https:\/\/github.com\/Fran-A-Dev\/sitemap-headlesswp\">GitHub<\/a>.<\/p>\n\n\n\n<p>I want to give a major shoutout and credit to <a href=\"https:\/\/dipankarmaikap.com\/\">Dipankar Maikap<\/a> who created the WP Sitemap Rest Api plugin and assisted me in the creation of this tutorial.  <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you will learn how to create sitemaps in Headless WordPress using Next.js and the WP Sitemap Rest API plugin. (Just a note, if you need a foundational [&hellip;]<\/p>\n","protected":false},"author":20,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_EventAllDay":false,"_EventTimezone":"","_EventStartDate":"","_EventEndDate":"","_EventStartDateUTC":"","_EventEndDateUTC":"","_EventShowMap":false,"_EventShowMapLink":false,"_EventURL":"","_EventCost":"","_EventCostDescription":"","_EventCurrencySymbol":"","_EventCurrencyCode":"","_EventCurrencyPosition":"","_EventDateTimeSeparator":"","_EventTimeRangeSeparator":"","_EventOrganizerID":[],"_EventVenueID":[],"_OrganizerEmail":"","_OrganizerPhone":"","_OrganizerWebsite":"","_VenueAddress":"","_VenueCity":"","_VenueCountry":"","_VenueProvince":"","_VenueState":"","_VenueZip":"","_VenuePhone":"","_VenueURL":"","_VenueStateProvince":"","_VenueLat":"","_VenueLng":"","_VenueShowMap":false,"_VenueShowMapLink":false,"footnotes":""},"categories":[23],"tags":[],"class_list":["post-633","post","type-post","status-publish","format-standard","hentry","category-headless"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Sitemaps in Headless WordPress with Next.js - Builders<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Sitemaps in Headless WordPress with Next.js - Builders\" \/>\n<meta property=\"og:description\" content=\"In this tutorial, you will learn how to create sitemaps in Headless WordPress using Next.js and the WP Sitemap Rest API plugin. (Just a note, if you need a foundational [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/\" \/>\n<meta property=\"og:site_name\" content=\"Builders\" \/>\n<meta property=\"article:published_time\" content=\"2022-09-09T23:24:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-04-26T17:24:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-05-at-5.17.12-PM-1024x309.png\" \/>\n<meta name=\"author\" content=\"Francis Agulto\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@wpebuilders\" \/>\n<meta name=\"twitter:site\" content=\"@wpebuilders\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Francis Agulto\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/\"},\"author\":{\"name\":\"Francis Agulto\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/person\\\/bcdcb4ac0b215c34b6b30e440a24dc54\"},\"headline\":\"Sitemaps in Headless WordPress with Next.js\",\"datePublished\":\"2022-09-09T23:24:29+00:00\",\"dateModified\":\"2023-04-26T17:24:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/\"},\"wordCount\":1897,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2022\\\/09\\\/Screen-Shot-2022-09-05-at-5.17.12-PM-1024x309.png\",\"articleSection\":[\"Headless\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/\",\"name\":\"Sitemaps in Headless WordPress with Next.js - Builders\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2022\\\/09\\\/Screen-Shot-2022-09-05-at-5.17.12-PM-1024x309.png\",\"datePublished\":\"2022-09-09T23:24:29+00:00\",\"dateModified\":\"2023-04-26T17:24:15+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/#primaryimage\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2022\\\/09\\\/Screen-Shot-2022-09-05-at-5.17.12-PM-1024x309.png\",\"contentUrl\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2022\\\/09\\\/Screen-Shot-2022-09-05-at-5.17.12-PM-1024x309.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/sitemaps-headless-wordpress-next-js\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Sitemaps in Headless WordPress with Next.js\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#website\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\",\"name\":\"Builders\",\"description\":\"Reimagining the way we build with WordPress.\",\"publisher\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#organization\",\"name\":\"WP Engine\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/WP-Engine-Horizontal@2x.png\",\"contentUrl\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/wp-content\\\/uploads\\\/2024\\\/05\\\/WP-Engine-Horizontal@2x.png\",\"width\":348,\"height\":68,\"caption\":\"WP Engine\"},\"image\":{\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/wpebuilders\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCh1WuL54XFb9ZI6m6goFv1g\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/#\\\/schema\\\/person\\\/bcdcb4ac0b215c34b6b30e440a24dc54\",\"name\":\"Francis Agulto\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g\",\"caption\":\"Francis Agulto\"},\"description\":\"Fran Agulto is a Developer Advocate at WP Engine. He is a lover of all things headless WordPress, Rock Climbing, and overall being stoked for people that love what they do and share that stoke with others! Follow me on Twitter for cool stoked headless WP!\",\"url\":\"https:\\\/\\\/wpengine.com\\\/builders\\\/author\\\/francis-agultowpengine-com-2-2-2-2-2-2-2-2-2-2-2-3\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Sitemaps in Headless WordPress with Next.js - Builders","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/","og_locale":"en_US","og_type":"article","og_title":"Sitemaps in Headless WordPress with Next.js - Builders","og_description":"In this tutorial, you will learn how to create sitemaps in Headless WordPress using Next.js and the WP Sitemap Rest API plugin. (Just a note, if you need a foundational [&hellip;]","og_url":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/","og_site_name":"Builders","article_published_time":"2022-09-09T23:24:29+00:00","article_modified_time":"2023-04-26T17:24:15+00:00","og_image":[{"url":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-05-at-5.17.12-PM-1024x309.png","type":"","width":"","height":""}],"author":"Francis Agulto","twitter_card":"summary_large_image","twitter_creator":"@wpebuilders","twitter_site":"@wpebuilders","twitter_misc":{"Written by":"Francis Agulto"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/#article","isPartOf":{"@id":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/"},"author":{"name":"Francis Agulto","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/person\/bcdcb4ac0b215c34b6b30e440a24dc54"},"headline":"Sitemaps in Headless WordPress with Next.js","datePublished":"2022-09-09T23:24:29+00:00","dateModified":"2023-04-26T17:24:15+00:00","mainEntityOfPage":{"@id":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/"},"wordCount":1897,"commentCount":0,"publisher":{"@id":"https:\/\/wpengine.com\/builders\/#organization"},"image":{"@id":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/#primaryimage"},"thumbnailUrl":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-05-at-5.17.12-PM-1024x309.png","articleSection":["Headless"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/","url":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/","name":"Sitemaps in Headless WordPress with Next.js - Builders","isPartOf":{"@id":"https:\/\/wpengine.com\/builders\/#website"},"primaryImageOfPage":{"@id":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/#primaryimage"},"image":{"@id":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/#primaryimage"},"thumbnailUrl":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-05-at-5.17.12-PM-1024x309.png","datePublished":"2022-09-09T23:24:29+00:00","dateModified":"2023-04-26T17:24:15+00:00","breadcrumb":{"@id":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/#primaryimage","url":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-05-at-5.17.12-PM-1024x309.png","contentUrl":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2022\/09\/Screen-Shot-2022-09-05-at-5.17.12-PM-1024x309.png"},{"@type":"BreadcrumbList","@id":"https:\/\/wpengine.com\/builders\/sitemaps-headless-wordpress-next-js\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wpengine.com\/builders\/"},{"@type":"ListItem","position":2,"name":"Sitemaps in Headless WordPress with Next.js"}]},{"@type":"WebSite","@id":"https:\/\/wpengine.com\/builders\/#website","url":"https:\/\/wpengine.com\/builders\/","name":"Builders","description":"Reimagining the way we build with WordPress.","publisher":{"@id":"https:\/\/wpengine.com\/builders\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wpengine.com\/builders\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/wpengine.com\/builders\/#organization","name":"WP Engine","url":"https:\/\/wpengine.com\/builders\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/","url":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png","contentUrl":"https:\/\/wpengine.com\/builders\/wp-content\/uploads\/2024\/05\/WP-Engine-Horizontal@2x.png","width":348,"height":68,"caption":"WP Engine"},"image":{"@id":"https:\/\/wpengine.com\/builders\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/wpebuilders","https:\/\/www.youtube.com\/channel\/UCh1WuL54XFb9ZI6m6goFv1g"]},{"@type":"Person","@id":"https:\/\/wpengine.com\/builders\/#\/schema\/person\/bcdcb4ac0b215c34b6b30e440a24dc54","name":"Francis Agulto","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0c8a05c76944fc987d57296c96dc368055844527088c0aa44297edbfa8b82546?s=96&d=mm&r=g","caption":"Francis Agulto"},"description":"Fran Agulto is a Developer Advocate at WP Engine. He is a lover of all things headless WordPress, Rock Climbing, and overall being stoked for people that love what they do and share that stoke with others! Follow me on Twitter for cool stoked headless WP!","url":"https:\/\/wpengine.com\/builders\/author\/francis-agultowpengine-com-2-2-2-2-2-2-2-2-2-2-2-3\/"}]}},"_links":{"self":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts\/633","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/comments?post=633"}],"version-history":[{"count":0,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/posts\/633\/revisions"}],"wp:attachment":[{"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/media?parent=633"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/categories?post=633"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpengine.com\/builders\/wp-json\/wp\/v2\/tags?post=633"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}