How to create a dynamic sitemap.xml for your Sveltekit app.
Tags: webdev, svelte, sveltekit, javascript
Published: 2023-08-15 14:38:21

Search Engine Optimization (SEO) is a critical aspect of making your website discoverable and ranking well in search engine results. Sitemaps play a significant role in enhancing SEO by providing search engines with a structured roadmap of your website's content. They help search engines understand the organization of your site, index its pages efficiently, and ensure that your latest and most important content gets appropriately prioritized.

So, you've built your nice SvelteKit application, a blog maybe?, but you need to submit a sitemap.xml file to Google search console. Let me guess, your routes are dynamic so you can't just manually index all your routes?. Don't worry, I'll show you how.

I recently just built my blog at [n3-rd.tech](https://www.n3-rd.tech/) and had this exact problem, using the official [Dev.to API](https://dev.to/api), I had all my posts dynamically generated and it was a big problem. How did I get a solution?, well here it is.

## Creating a Route for our sitemap

First thing we'll do is create a new directory in our `src/routes` folder named `sitemap.xml` (directory, not a file!). Then in our directory, we'll create a `+server.js` file

## Coding the actual sitemap
In our `+server.js` file, we'll start by setting the headers and setting our content type to xml

``` javascript
export async function GET({ fetch, setHeaders })  {
setHeaders({
'Content-Type': 'application/xml'
});
```
When we've done that, we'll define our site and make a fetch request to get our posts

``` javascript
const site  =  'https://www.website.';
const response  =  await  fetch('https://dev.to/api/articles?username=yourUsername');
if (!response.ok) {
throw  new  Error('Failed to fetch posts.');
}
const posts = await response.json();
```
Our site url is defined in the `site` variable and we fetch the our posts and throw an error if that fails, then we define our response in the posts variable.
***note that you may be fetching your posts with a different method, adjust the fetch request to adapt your own method.***

Next, we'll define our sitemap like this :

```javascript
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>${site}</loc>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
${posts.map(post  =>  `
<url>
<loc>${site}/articles/${post.id}</loc>
<changefreq>weekly</changefreq>
<lastmod>${post.published_at.split('T')[0]}</lastmod>
</url>
`).join('')}
</urlset>`;
return new Response(sitemap);
}
```
We first define our base url using our `site`  variable created earlier, we then use the `.map()` function on the `posts` array to iterate through each article and generate XML `<url>` elements for them. Each `<url>` element contains a `<loc>` element with the article URL, a `<changefreq>` element with 'weekly', and a `<lastmod>` element with the article's published date. The code `split('T')[0]` is optional and I only used it to format the date provided by the API.
The `.join('')` function is then used to concatenate all the generated `<url>` elements into a single string.
Our constructed XML sitemap is then returned as a response using the `Response` constructor, passing in the `sitemap` string.
***Note: You should adjust this code based on your website structure***

The final code should look similar to this:

```javascript
export async function GET({ fetch, setHeaders })  {
setHeaders({
'Content-Type': 'application/xml'
});

const site  =  'https://www.website.';
const response  =  await  fetch('https://dev.to/api/articles?username=yourUsername');
if (!response.ok) {
throw  new  Error('Failed to fetch posts.');
}
const posts = await response.json();

const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>${site}</loc>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
${posts.map(post  =>  `
<url>
<loc>${site}/articles/${post.id}</loc>
<changefreq>weekly</changefreq>
<lastmod>${post.published_at.split('T')[0]}</lastmod>
</url>
`).join('')}
</urlset>`;
return new Response(sitemap);
}
```
That's all!, our sitemap should be available through the `/sitemap.xml` route.

![yay](https://media.giphy.com/media/3NtY188QaxDdC/giphy.gif)
Please Like, share and comment any issues below, Thank You

I will also soon be publishing it on GeeksforGeeks” with the text GeeksforGeeks being linked to https://www.geeksforgeeks.org/.