Core Concepts

Introduction

When working with a CMS or external data sources, you may need to generate sitemap URLs dynamically at runtime.

The module supports two types of data sources:

  • JSON responses from API endpoints
  • XML sitemaps from external sources

Using External XML Sitemaps

If you have an existing XML sitemap, you can reference it directly in your configuration:

nuxt.config.ts
export default defineNuxtConfig({
  sitemap: {
    sources: [
      'https://example.com/sitemap.xml',
    ]
  }
})

Dynamic URLs from External APIs

When fetching dynamic URLs from external APIs, you have two main approaches:

  1. Direct source configuration - Use when the API returns data in the correct format
  2. Custom API endpoint - Use when you need to transform data or implement caching

1. Using Source Configuration

For APIs that require authentication or custom headers, provide sources as an array with fetch options:

nuxt.config.ts
export default defineNuxtConfig({
  sitemap: {
    sources: [
      // Unauthenticated endpoint
      'https://api.example.com/pages/urls',
      // Authenticated endpoint
      [
        'https://authenticated-api.example.com/pages/urls',
        { headers: { Authorization: 'Bearer <token>' } }
      ]
    ]
  }
})

2. Creating Custom Endpoints

Step 1: Create the API endpoint

Use the defineSitemapEventHandler() helper to create type-safe sitemap endpoints:

// server/api/__sitemap__/urls.ts
import { defineSitemapEventHandler } from '#imports'
import type { SitemapUrlInput } from '#sitemap/types'

export default defineSitemapEventHandler(() => {
  return [
    {
      loc: '/about-us',
      // Specify which sitemap this URL belongs to
      _sitemap: 'pages',
    },
  ] satisfies SitemapUrlInput[]
})

Step 2: Configure the endpoint

Add your custom endpoint to the sitemap configuration:

export default defineNuxtConfig({
  sitemap: {
    sources: [
      '/api/__sitemap__/urls',
    ]
  }
})

Handling Pre-Encoded URLs

By default, the module automatically encodes URL paths. This handles special characters like spaces and unicode (e.g., emojis, accented characters).

If your API or CMS returns URLs that are already encoded, mark them with _encoded: true to prevent double-encoding.

server/api/__sitemap__/urls.ts
import { defineSitemapEventHandler } from '#imports'

export default defineSitemapEventHandler(async () => {
  // URLs from your API are already encoded
  const urls = await $fetch<{ path: string }[]>('https://api.example.com/pages')
  // e.g. [{ path: '/products/%24pecial-offer' }, { path: '/blog/%F0%9F%98%85' }]

  return urls.map(url => ({
    loc: url.path,
    _encoded: true,
  }))
})
When _encoded: true is set, the module skips automatic encoding entirely. Make sure your URLs are properly encoded.
Did this page help you?