How to create a dynamic sitemap.xml for your Sveltekit app.
Godwin Jemegah
Posted on August 15, 2023
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 and had this exact problem, using the official 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
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
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 :
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:
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.
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/.
Posted on August 15, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.