With Sitecore 10 and SXA this is less of an issue than in previous iterations. Aside from regenerating the sitemap every time that you publish a page (which we may cover in another article), what if you generated it on a schedule, say, every 24 hrs.
One way we can accomplish this is by setting up a task agent. This is different than setting up tasks within Content Editor. I'm referring to the ones set up in the Sitecore configuration itself.
Setup And Configuration
Part of what we might want is control over what gets included in the sitemap. This could be not only template type but also perhaps what we want to exclude. If we have multiple sites, one aspect of this Item might be the selection of the site (or sites) to include in the sitemap.
Creating an item template to track all that information is simple enough and not something we're going to go in-depth in today.
Within a patch file, we can create our agents to kick off at specific times.
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<sitecore>
<scheduling>
<agent name="WWWSiteMap" type="ABCCompany.Feature.Sitemap.Tasks.SitemapTask,ABCCompany.Feature.Sitemap" method="Run" interval="12:00:00" patch:after="agent[@type='Sitecore.Tasks.CompactClientDataAgent']">
<SiteMapId>{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}</SiteMapId>
</agent>
</scheduling>
</sitecore>
</configuration>
Here are some important parts of our configuration.
name
- Used to ensure our agent is unique. Theoretically, if we had a dozen sites, we could use the same commands, just set-up a new agent.type
- Points to our sitemap task class.method
- Which method to use in said class.interval
- How often to run said method.patch:after
- Where to add the configuration.SiteMapId
- TheGUID
of the item that contains our sitemap configuration referenced above.
The Code
With the configuration in place, we now need code to kick off the sitemap generation.
namespace ABCCompany.Feature.Sitemap.Tasks
{
class SitemapTask
{
private ISitemapRepository _repo;
<span class="hljs-comment">// Same name as in the configuration file to capture what is passed to the agent</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> SiteMapId { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Run</span>(<span class="hljs-params"></span>)</span>
{
<span class="hljs-keyword">if</span> (String.IsNullOrEmpty(<span class="hljs-keyword">this</span>.SiteMapId)) <span class="hljs-keyword">return</span>;
<span class="hljs-comment">// Get our Sitemap configuration item</span>
<span class="hljs-keyword">var</span> db = Sitecore.Data.Database.GetDatabase(<span class="hljs-string">"web"</span>);
<span class="hljs-keyword">var</span> source = db.GetItem(<span class="hljs-keyword">new</span> Sitecore.Data.ID(<span class="hljs-keyword">this</span>.SiteMapId));
<span class="hljs-keyword">if</span> (source == <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span>;
<span class="hljs-comment">// setup Sitemap repo</span>
_repo = <span class="hljs-keyword">new</span> SitemapRepository();
<span class="hljs-comment">// Generate and store our sitemap.</span>
_repo.CreateSitemapFile(source);
}
}
}
What happens within _repo.CdreateSitemapFile(source)
really depends on your site, what configurations you're looking to control, etc.
For us, it was important to generate an actual sitemap.xml
file and that's something that occurs in this function. This way it wasn't trying to generate the sitemap on a specific web call. If your site is over a few hundred items, I strongly recommend against trying to generate the sitemap on-demand.