Building a dynamic sitemap
A sitemap helps search engines understand and index your website more effectively. Think of it as a map that guides search crawlers through your content, showing them what pages exist and how often they change.
Just like how we built SEO overrides to give content editors control over metadata, a well-structured sitemap gives search engines clear guidance about your content hierarchy and update frequency.
Why this approach?
Search engines like Google use sitemaps as a primary method to discover and understand your content. While they can crawl your site naturally through links, a sitemap:
- Ensures all your content is discoverable, even pages that might be deep in your site structure
- Helps search engines understand when content was last updated
- Allows you to indicate content priority
- Speeds up the indexing process for new content
This is especially important for dynamic content managed through Sanity, where pages might be added or updated frequently.
Learning objectives
By the end of this lesson, you'll be able to:
- Create a dynamic sitemap that updates automatically
- Connect your sitemap to Sanity content
- Implement graceful error handling
Understanding sitemaps
Before diving into the code, let's understand what makes a good sitemap from a technical perspective:
- XML Format: Search engines expect a specific XML format
- Last Modified Dates: Helps search engines know when content was updated
- Change Frequency: Indicates how often content changes
- Priority: Suggests the importance of pages
Building the sitemap
Let's start with a simple GROQ query to fetch our pages:
const sitemapQuery = `*[_type == "page" && defined(slug.current)] {
"slug": slug.current,
_updatedAt
}`;
This query:
- Gets all documents of type
page
- Makes sure they have a slug
- Fetches both the slug and last updated date
Now let's create your sitemap function:
import { MetadataRoute } from "next";
import { client } from "@/lib/sanity/client";
import sitemapQuery from "~/lib/queries/sitemap";
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
try {
// Fetch pages from Sanity
const pages = await client.fetch(sitemapQuery);
if (!pages) return [];
const baseUrl = process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000";
// Transform pages into sitemap format
return pages.map((page: { slug: string; _updatedAt: string }) => ({
url: `${baseUrl}/${page.slug}`,
lastModified: new Date(page._updatedAt),
changeFrequency: "weekly" as const,
priority: 1,
}));
} catch (error) {
console.error("Failed to generate sitemap:", error);
return [];
}
}
Let's break down what this code does:
- URL Construction: Builds full URLs using your site's
baseUrl
- Metadata: Uses the
_updatedAt
field to set the last modified date - Error Handling: Returns an empty array and
console.error
if something goes wrong
Testing your sitemap
After deploying your changes, you can test your sitemap by visiting /sitemap.xml
on your site.
You should see something like this:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://yoursite.com/about</loc>
<lastmod>2024-01-01T12:00:00.000Z</lastmod>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<!-- More URLs... -->
</urlset>
Even if your sitemap looks correct, checking with a sitemap validator tool is recommended. Especially as your website grows. It's very easy to miss validation errors. A solid option is XML Sitemaps (opens in a new tab) for a free and quick check.
Best practices
To ensure your sitemap is doing what it's meant to, keep these points in mind:
- Regular Updates: Your sitemap should update when content changes
- Size Limits: Keep under 50,000 URLs per sitemap file
- Valid URLs: Ensure all URLs are properly formatted
At this stage, your sitemap will now automatically update whenever you publish new content in Sanity, helping search engines discover and index your content.
As you continue to enhance your sitemap implementation and expand out through other document types, you may want to consider adding different priorities for different page types to help search engines understand the relative importance of your content.
Next, you'll explore structured data and JSON-LD - a clever way of reusing your documents for set and forget SEO benefits.