---
title: "Nuxt Sitemap Configuration Guide"
description: "Generate sitemaps for Nuxt with the @nuxtjs/sitemap module or server routes for dynamic content."
canonical_url: "https://nuxtseo.com/learn-seo/nuxt/controlling-crawlers/sitemaps"
last_updated: "2026-01-04"
---

<key-takeaways>

- Sitemaps limited to 50,000 URLs or 50MB. Use sitemap index for larger sites
- Skip `changefreq` and `priority`. Google ignores them, only `lastmod` matters
- Nuxt Sitemap module auto-generates from pages/ and handles large sites

</key-takeaways>

This guide covers sitemap strategy and configuration. For module installation and API reference, see the [Nuxt Sitemap documentation](/docs/sitemap/getting-started/introduction).

The `sitemap.xml` file helps search engines discover your pages. Google considers sites "small" if they have [500 pages or fewer](https://developers.google.com/search/docs/crawling-indexing/sitemaps/overview). You likely need a sitemap if you exceed this, have new sites with few backlinks, or update content frequently. For new sites, pair your sitemap with a solid [internal linking structure](/learn-seo/nuxt/routes-and-rendering/internal-linking) and a [pre-launch warmup](/learn-seo/pre-launch-warmup) strategy to accelerate discovery.

## Static Sitemap

For small sites under 100 pages, create a static sitemap in your public directory:

```dir
public/
  sitemap.xml
```

Add your URLs with proper formatting:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://mysite.com/</loc>
    <lastmod>2024-11-03</lastmod>
  </url>
  <url>
    <loc>https://mysite.com/about</loc>
    <lastmod>2024-12-10</lastmod>
  </url>
</urlset>
```

Sitemaps are limited to [50,000 URLs or 50MB uncompressed](https://developers.google.com/search/docs/crawling-indexing/sitemaps/build-sitemap). Use UTF-8 encoding and absolute URLs only.

## Dynamic Generation

For sites with frequently changing content (e-commerce, blogs, news) or [programmatic SEO](/learn-seo/nuxt/routes-and-rendering/programmatic-seo) pages, generate sitemaps server-side with a Nitro route:

```ts [server/routes/sitemap.xml.ts]
export default defineEventHandler(async (event) => {
  const pages = await fetchAllPages()

  const urls = pages.map(page => `
  <url>
    <loc>https://mysite.com${page.path}</loc>
    <lastmod>${page.updatedAt}</lastmod>
  </url>`).join('\n')

  const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls}
</urlset>`

  setHeader(event, 'Content-Type', 'application/xml')
  return sitemap
})
```

This runs on every request. For better performance, use the Sitemap module which caches and optimizes sitemap generation.

## Automatic Generation

Nuxt generates sitemaps automatically with the Sitemap module:

<module-card slug="sitemap">



</module-card>

Install and configure:

```bash
npx nuxi@latest module add sitemap
```

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  modules: ['@nuxtjs/sitemap'],
  site: {
    url: 'https://mysite.com'
  }
})
```

This creates a sitemap from your routes automatically. For static sites, it's generated at build time. For dynamic sites, it's generated on request.

The module handles:

- Route discovery from `pages/` directory
- Dynamic routes with route rules
- Sitemap indexes for large sites
- Image and video sitemaps
- News sitemaps
- Multi-language sitemaps

For full configuration options, see the [Sitemap module docs](/docs/sitemap/getting-started/introduction).

## XML Sitemap Tags

A basic sitemap uses these elements:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://mysite.com/page</loc>
    <lastmod>2024-11-03</lastmod>
  </url>
</urlset>
```

### Required and Optional Tags

<table>
<thead>
  <tr>
    <th>
      Tag
    </th>
    
    <th>
      Status
    </th>
    
    <th>
      Google Uses?
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code className="language-html shiki shiki-themes github-light github-light material-theme-palenight" language="html" style="">
        <span class="sx-uw">
          <
        </span>
        
        <span class="sFfpx">
          loc
        </span>
        
        <span class="sx-uw">
          >
        </span>
      </code>
    </td>
    
    <td>
      Required
    </td>
    
    <td>
      Yes, the page URL
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-html shiki shiki-themes github-light github-light material-theme-palenight" language="html" style="">
        <span class="sx-uw">
          <
        </span>
        
        <span class="sFfpx">
          lastmod
        </span>
        
        <span class="sx-uw">
          >
        </span>
      </code>
    </td>
    
    <td>
      <strong>
        Crucial
      </strong>
    </td>
    
    <td>
      Yes, the primary signal for "Freshness" in 2026
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-html shiki shiki-themes github-light github-light material-theme-palenight" language="html" style="">
        <span class="sx-uw">
          <
        </span>
        
        <span class="sFfpx">
          changefreq
        </span>
        
        <span class="sx-uw">
          >
        </span>
      </code>
    </td>
    
    <td>
      Skip
    </td>
    
    <td>
      <a href="https://developers.google.com/search/blog/2023/06/sitemaps-lastmod-ping" rel="nofollow">
        No, Google ignores this
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-html shiki shiki-themes github-light github-light material-theme-palenight" language="html" style="">
        <span class="sx-uw">
          <
        </span>
        
        <span class="sFfpx">
          priority
        </span>
        
        <span class="sx-uw">
          >
        </span>
      </code>
    </td>
    
    <td>
      Skip
    </td>
    
    <td>
      <a href="https://developers.google.com/search/blog/2014/10/best-practices-for-xml-sitemaps-rssatom" rel="nofollow">
        No, Google ignores this
      </a>
    </td>
  </tr>
</tbody>
</table>

#### lastmod: The Freshness Signal

In 2026, `<lastmod>` is more than just a timestamp; it's the trigger for AI "Freshness" algorithms. Search engines like [Perplexity](https://perplexity.ai) and Google's AI Overviews prioritize content with a recent, accurate `lastmod`.

- **Be Honest**: Only update the date when content changes. Falsely updating dates leads to loss of trust.
- **Micro-updates count**: Small data updates or fact corrections are valid reasons to update `lastmod`.

## IndexNow: Real-time Indexing

While sitemaps are "pull-based" (crawlers check them), **IndexNow** is "push-based". It's a protocol that allows you to instantly notify search engines (Bing, Yandex, Seznam) when you create, update, or delete content.

The [Nuxt Sitemap module](/docs/sitemap/getting-started/introduction) supports IndexNow by default. It ensures that search engines discover your new content within minutes rather than hours.

## Sitemap Index for Large Sites

If you exceed 50,000 URLs or 50MB, [split your sitemap into multiple files](https://developers.google.com/search/docs/crawling-indexing/sitemaps/large-sitemaps):

```xml [sitemap-index.xml]
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <loc>https://mysite.com/sitemap-products.xml</loc>
    <lastmod>2024-11-03</lastmod>
  </sitemap>
  <sitemap>
    <loc>https://mysite.com/sitemap-blog.xml</loc>
    <lastmod>2024-12-10</lastmod>
  </sitemap>
</sitemapindex>
```

Submit the index file to [Google Search Console](/learn-seo/nuxt/launch-and-listen/search-console). It will crawl all referenced sitemaps. [Maximize URLs per sitemap](https://developers.google.com/search/blog/2014/10/best-practices-for-xml-sitemaps-rssatom) rather than creating many small files.

The Sitemap module handles this automatically when your site exceeds limits.

## Specialized Sitemaps

### News Sitemap

News publishers should create [separate news sitemaps](https://developers.google.com/search/docs/crawling-indexing/sitemaps/news-sitemap) with articles from the last 2 days:

```xml [sitemap-news.xml]
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
  <url>
    <loc>https://mysite.com/article</loc>
    <news:news>
      <news:publication>
        <news:name>Site Name</news:name>
        <news:language>en</news:language>
      </news:publication>
      <news:publication_date>2024-12-10T12:00:00+00:00</news:publication_date>
      <news:title>Article Title</news:title>
    </news:news>
  </url>
</urlset>
```

Remove articles older than 2 days to keep the sitemap fresh. Don't create new sitemaps daily. Update the existing one.

### Image Sitemap

For galleries or image-heavy sites, add image metadata:

```xml [sitemap.xml]
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
  <url>
    <loc>https://mysite.com/page</loc>
    <image:image>
      <image:loc>https://mysite.com/image.jpg</image:loc>
      <image:title>Image Title</image:title>
    </image:image>
  </url>
</urlset>
```

[Image sitemaps help Google find images loaded via JavaScript](https://developers.google.com/search/docs/crawling-indexing/sitemaps/image-sitemaps) or not directly linked in HTML.

## Submit to Google Search Console

After generating your sitemap, [submit it to Google Search Console](https://support.google.com/webmasters/answer/7451001):

1. [Verify site ownership](https://seotesting.com/google-search-console/how-to-create-a-sitemap-for-google-search-console/) (DNS, HTML file upload, or Google Analytics)
2. Navigate to **Sitemaps** under **Indexing**
3. Enter your sitemap URL: `https://mysite.com/sitemap.xml`
4. Click **Submit**

Google processes the sitemap and reports status:

- **Success**: sitemap accepted, pages discovered
- **Pending**: processing in progress
- **Couldn't fetch**: URL wrong or blocked by robots.txt

Check the Sitemaps report for coverage stats, indexing errors, and discovered URLs.

### Before Submitting

Validate your sitemap:

- XML syntax is valid (use an [online validator](https://www.xml-sitemaps.com/validate-xml-sitemap.html))
- All URLs return 200 status (not 404 or 500)
- URLs match [canonical URLs](/learn-seo/nuxt/controlling-crawlers/canonical-urls) exactly
- `<lastmod>` dates are accurate
- File uses UTF-8 encoding

### Alternative Submission

Reference your sitemap in `robots.txt`:

```txt [public/robots.txt]
User-agent: *
Allow: /

Sitemap: https://mysite.com/sitemap.xml
```

Google discovers this automatically when [crawling your robots.txt](/learn-seo/nuxt/controlling-crawlers/robots-txt).

### Troubleshooting "Couldn't Fetch"

A common issue after submitting: Google Search Console shows **"Couldn't fetch"** or **"Sitemap could not be read"** even though the sitemap validates correctly and is accessible in the browser. This is always a [Google-side delay](https://github.com/nuxt-modules/sitemap/issues/125), not a problem with your sitemap.

Before panicking:

1. **Use the URL Inspection tool** in Search Console. Paste your sitemap URL and click **Live test**. If Page fetch shows "Successful" and Crawl allowed shows "Yes", your sitemap is fine. Google hasn't processed it yet.
2. **Wait 24 to 48 hours**. Most "Couldn't fetch" errors resolve on their own as Google retries.

If the error persists after 48 hours:

- **Remove and resubmit**. Delete the sitemap from Search Console, then resubmit it. This forces Google to re-fetch from scratch.
- **Change the sitemap URL**. If resubmission doesn't work, rename the sitemap path (for example, from `/sitemap.xml` to `/sitemap_index.xml` using the `sitemapName` option in the Sitemap module). Google treats this as a new sitemap and fetches it immediately.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  sitemap: {
    sitemapName: 'sitemap_index.xml'
  }
})
```

<callout type="info">

This issue is especially common with sitemap indexes that contain multiple child sitemaps (for example, one per locale). Google may fetch some children successfully while others stay stuck. The same workarounds apply: wait, then resubmit or rename if needed.

</callout>
