---
title: "Sitemap Reader"
description: "Parse and traverse sitemap documents with Nuxt Sitemap's runtime-neutral utilities."
canonical_url: "https://nuxtseo.com/docs/sitemap/api/xml-parsing"
last_updated: "2026-08-10T19:03:13.482Z"
---

Nuxt Sitemap re-exports its runtime-neutral parser and reader from
`@nuxtjs/sitemap/utils`. They work in Node, browsers, Bun, and workerd without
importing Nuxt or H3.

## Parse a document

`collectSitemap` accepts strings, bytes, iterables, and `ReadableStream` bodies.
It detects XML URL sets, sitemap indexes, RSS 2.0, Atom 1.0, and gzip content.
Text sitemaps require the explicit `{ formatHint: 'text' }` option.

```ts
import { collectSitemap } from '@nuxtjs/sitemap/utils'

const result = await collectSitemap(response.body!)
if (result._tag !== 'document')
  throw new Error(result.issues.map(issue => issue.message).join('; '))

console.log(result.document)
console.log(result.completeness)
```

Expected document failures are tagged values. Unexpected input stream failures
propagate. URL strings and sitemap attributes remain raw evidence; validation
issues do not rewrite them.

## Stream events

`parseSitemap` incrementally emits the document kind, entries, issues, then one
terminal `end` event. It applies input backpressure and retains only the current
record. Persisted consumers must observe `end` before treating a document as
complete.

```ts
import { parseSitemap } from '@nuxtjs/sitemap/utils'

for await (const event of parseSitemap(response.body!)) {
  if (event._tag === 'url')
    console.log(event.entry.loc)
  if (event._tag === 'end')
    console.log(event.completeness)
}
```

The defaults are 50 MiB after decompression, 50,000 entries, and 1 MiB per
entry. Configure them with `maxDecodedBytes`, `maxEntries`, and
`maxEntryBytes`. Caps produce explicit partial completeness.

## Traverse indexes

Network access is injected. The reader asks the target authorizer before every
root, redirect, and index child. The generic Fetch adapter requests manual
redirect handling and makes no DNS security claim.

```ts
import {
  createFetchDocumentLoader,
  createSitemapReader,
} from '@nuxtjs/sitemap/utils'

const reader = createSitemapReader({
  loadDocument: createFetchDocumentLoader({ fetch }),
  authorizeTarget: async () => ({ _tag: 'allow' }),
})

const result = await reader.walk('https://example.com/sitemap.xml')
```
