Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

@power-seo/sitemap

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@power-seo/sitemap

XML sitemap generation, streaming, and validation with image, video, and news support

latest
Source
npmnpm
Version
1.0.12
Version published
Maintainers
1
Created
Source

@power-seo/sitemap

sitemap banner

XML sitemap generation for TypeScript — streaming output, automatic index splitting, image/video/news extensions, and URL validation — works in Next.js, Remix, Express, and edge runtimes with zero runtime dependencies.

npm version npm downloads Socket License: MIT TypeScript tree-shakeable

@power-seo/sitemap produces standards-compliant <urlset> and <sitemapindex> XML from typed URL arrays. Provide a hostname and URL list — get back a valid XML string ready to serve as Content-Type: application/xml. For large catalogs, stream chunks with constant memory usage or auto-split at the 50,000-URL spec limit with a generated index file. All six functions are independently importable and tree-shakeable.

Zero runtime dependencies — only @power-seo/core as a peer.

Why @power-seo/sitemap?

WithoutWith
Spec compliance❌ Hand-built XML, wrong namespaces✅ Correct <urlset> + namespace declarations
Large sites❌ Single file breaks at 50,000 URLs✅ Auto-split + sitemap index generation
Memory usage❌ String concat spikes on large catalogs✅ Synchronous generator yields chunks
Image indexing❌ Product images undiscoverable<image:image> extension per URL
Video SEO❌ No structured video metadata<video:video> extension with title, duration
News sitemaps❌ Missing publication + date tags<news:news> extension for Google News
Hostname handling❌ Hardcode absolute URLs everywhere✅ Pass hostname once; use relative loc paths
Validation❌ Silent bad data reaches GooglevalidateSitemapUrl() returns errors + warnings

Sitemap Generator Comparison

Features

  • Full sitemap spec support<loc>, <lastmod>, <changefreq>, <priority>, all optional elements
  • Hostname + relative paths — pass hostname in config; loc can be a relative path like /about
  • Image sitemap extension<image:image> tags with loc, caption, title, geoLocation, license
  • Video sitemap extension<video:video> tags with title, description, thumbnail, duration, rating
  • News sitemap extension<news:news> tags with publication name, language, date
  • Streaming generationstreamSitemap() is a synchronous generator yielding XML string chunks; no memory spike on large lists
  • Automatic index splittingsplitSitemap() chunks at MAX_URLS_PER_SITEMAP (50,000) and returns both sitemaps and the index XML
  • Sitemap index generationgenerateSitemapIndex() creates a <sitemapindex> pointing to child sitemaps
  • Smart namespace detectiongenerateSitemap() only declares XML namespaces for extensions (image, video, news) that are actually used
  • URL validationvalidateSitemapUrl() returns { valid, errors, warnings } without throwing
  • Next.js App Router adaptertoNextSitemap() converts SitemapURL[] to the MetadataRoute.Sitemap[] format for app/sitemap.ts
  • Constants exportedMAX_URLS_PER_SITEMAP (50,000) and MAX_SITEMAP_SIZE_BYTES (52,428,800)
  • Framework-agnostic — works in Next.js API routes, Remix loaders, Express, Fastify, and edge runtimes
  • Full TypeScript support — typed SitemapURL, SitemapImage, SitemapVideo, SitemapNews, SitemapConfig
  • Zero runtime dependencies — pure TypeScript, no external XML libraries
  • Tree-shakeable — import only the functions you use

Google Search Console Sitemap UI

Comparison

Feature@power-seo/sitemapnext-sitemapsitemap (npm)xmlbuilder2
Image sitemap extension
Video sitemap extension
News sitemap extension
Streaming generation
Auto index splitting
URL validation
Hostname + relative loc paths
Zero runtime dependencies
Edge runtime compatible
TypeScript-firstPartial
Tree-shakeable
Next.js app/sitemap.ts adapter

Sitemap Extensions Accuracy

Installation

npm install @power-seo/sitemap
yarn add @power-seo/sitemap
pnpm add @power-seo/sitemap

Quick Start

import { generateSitemap } from '@power-seo/sitemap';

const xml = generateSitemap({
  hostname: 'https://example.com',
  urls: [
    { loc: '/', lastmod: '2026-01-01', changefreq: 'daily', priority: 1.0 },
    { loc: '/about', changefreq: 'monthly', priority: 0.8 },
    { loc: '/blog/post-1', lastmod: '2026-01-15', priority: 0.6 },
  ],
});

// Returns valid XML string:
// <?xml version="1.0" encoding="UTF-8"?>
// <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
//   <url><loc>https://example.com/</loc>...

hostname is required — it is prepended to any loc value that is a relative path. Absolute loc values (starting with http) are used as-is.

Sitemap Streaming Benefit

Usage

Generating a Sitemap

generateSitemap() accepts a SitemapConfig with hostname and urls and returns a complete XML string.

import { generateSitemap } from '@power-seo/sitemap';

const xml = generateSitemap({
  hostname: 'https://example.com',
  urls: [
    { loc: '/', lastmod: '2026-01-01', changefreq: 'daily', priority: 1.0 },
    { loc: '/products', changefreq: 'weekly', priority: 0.9 },
    { loc: '/blog', changefreq: 'daily', priority: 0.8 },
  ],
});

// Serve as application/xml
res.setHeader('Content-Type', 'application/xml');
res.send(xml);

Streaming a Large Sitemap

streamSitemap() is a synchronous generator. It yields XML string chunks one <url> at a time — keeping memory usage constant regardless of catalog size.

import { streamSitemap } from '@power-seo/sitemap';

const urls = fetchAllProductUrls(); // Iterable<SitemapURL>

const stream = streamSitemap('https://example.com', urls);
for (const chunk of stream) {
  response.write(chunk);
}
response.end();

Splitting Large Sitemaps with an Index

splitSitemap() chunks a config at the 50,000-URL spec limit and returns all individual sitemap XML strings plus a sitemap index XML string that references them.

import { splitSitemap } from '@power-seo/sitemap';

const { index, sitemaps } = splitSitemap({
  hostname: 'https://example.com',
  urls: largeUrlArray, // more than 50,000 entries
});

// Write each sitemap file
for (const { filename, xml } of sitemaps) {
  fs.writeFileSync(`./public${filename}`, xml);
}

// Write the index (default filenames: /sitemap-0.xml, /sitemap-1.xml, ...)
fs.writeFileSync('./public/sitemap.xml', index);

Custom filename pattern:

const { index, sitemaps } = splitSitemap(
  { hostname: 'https://example.com', urls: largeUrlArray },
  '/sitemaps/part-{index}.xml', // default: '/sitemap-{index}.xml'
);

Generating a Sitemap Index Manually

Use generateSitemapIndex() when you maintain separate sitemaps per section or locale and want to combine them under a single index file.

import { generateSitemapIndex } from '@power-seo/sitemap';

const indexXml = generateSitemapIndex({
  sitemaps: [
    { loc: 'https://example.com/sitemap-pages.xml', lastmod: '2026-01-01' },
    { loc: 'https://example.com/sitemap-products.xml', lastmod: '2026-01-15' },
    { loc: 'https://example.com/sitemap-blog.xml', lastmod: '2026-01-20' },
  ],
});

Image Sitemaps

Add images to any SitemapURL entry to emit <image:image> extension tags:

import { generateSitemap } from '@power-seo/sitemap';

const xml = generateSitemap({
  hostname: 'https://example.com',
  urls: [
    {
      loc: '/products/blue-sneaker',
      lastmod: '2026-01-10',
      images: [
        {
          loc: 'https://cdn.example.com/sneaker-blue.jpg',
          caption: 'Blue sneaker — side view',
          title: 'Blue Running Sneaker',
        },
        {
          loc: 'https://cdn.example.com/sneaker-blue-top.jpg',
          caption: 'Blue sneaker — top view',
        },
      ],
    },
  ],
});

Validating URL Entries

validateSitemapUrl() checks a SitemapURL against the sitemap spec and returns structured errors and warnings — useful in CI or before serving.

import { validateSitemapUrl } from '@power-seo/sitemap';

const result = validateSitemapUrl({
  loc: '/about',
  priority: 1.5, // out of range
  changefreq: 'daily',
});

// result.valid   → false
// result.errors  → ['priority must be between 0.0 and 1.0']
// result.warnings → []

Next.js App Router — app/sitemap.ts Convention

Next.js App Router has a built-in app/sitemap.ts file convention that returns an array of URL objects (not XML). Use toNextSitemap() to convert SitemapURL[] to the required format:

// app/sitemap.ts
import { toNextSitemap } from '@power-seo/sitemap';

export default async function sitemap() {
  const urls = await fetchUrlsFromCms();

  return toNextSitemap(urls);
  // Returns NextSitemapEntry[] — Next.js renders the XML automatically
}

toNextSitemap() filters out invalid URLs and maps changefreq to changeFrequency as required by Next.js. The lastmod field is passed through as-is (string or Date).

Next.js App Router — Route Handler (XML)

For full control over the XML output (useful when you need image/video/news extensions), use a route handler instead:

// app/sitemap.xml/route.ts
import { generateSitemap } from '@power-seo/sitemap';

export async function GET() {
  const urls = await fetchUrlsFromCms();

  const xml = generateSitemap({
    hostname: 'https://example.com',
    urls,
  });

  return new Response(xml, {
    headers: { 'Content-Type': 'application/xml' },
  });
}

Remix Resource Route

// app/routes/sitemap[.xml].ts
import { generateSitemap } from '@power-seo/sitemap';
import type { LoaderFunctionArgs } from '@remix-run/node';

export async function loader({ request }: LoaderFunctionArgs) {
  const urls = await fetchUrlsFromDb();

  const xml = generateSitemap({
    hostname: 'https://example.com',
    urls,
  });

  return new Response(xml, {
    headers: { 'Content-Type': 'application/xml' },
  });
}

API Reference

generateSitemap(config)

function generateSitemap(config: SitemapConfig): string;
PropTypeRequiredDescription
hostnamestringBase URL prepended to relative loc paths (e.g. 'https://example.com')
urlsSitemapURL[]Array of URL entries
maxUrlsPerSitemapnumberOverride the 50,000-URL chunk size (used by splitSitemap)
outputDirstringOptional output directory hint (informational; does not write files)

streamSitemap(hostname, urls)

function streamSitemap(
  hostname: string,
  urls: Iterable<SitemapURL>,
): Generator<string, void, undefined>;

Synchronous generator. Yields XML string chunks — one for the XML declaration and opening tag, one per <url> block, and one for the closing tag. Does not buffer the full XML in memory.

ParamTypeDescription
hostnamestringBase URL prepended to relative loc paths
urlsIterable<SitemapURL>Any iterable of URL entries — arrays, generators, database cursors

splitSitemap(config, sitemapUrlPattern?)

function splitSitemap(
  config: SitemapConfig,
  sitemapUrlPattern?: string,
): { index: string; sitemaps: Array<{ filename: string; xml: string }> };

Splits a large URL set into multiple sitemap files and returns the index XML and all sitemap XMLs. The sitemapUrlPattern parameter controls generated filenames using {index} as a placeholder.

ParamTypeDefaultDescription
configSitemapConfigSame config as generateSitemap()
sitemapUrlPatternstring'/sitemap-{index}.xml'Filename pattern for each split sitemap

Return value:

FieldTypeDescription
indexstringSitemap index XML (<sitemapindex>) referencing all split files
sitemapsArray<{ filename: string; xml: string }>Each split sitemap with its filename and XML string

generateSitemapIndex(config)

function generateSitemapIndex(config: SitemapIndexConfig): string;
PropTypeDescription
sitemapsSitemapIndexEntry[]Array of { loc: string; lastmod?: string } entries

validateSitemapUrl(url)

function validateSitemapUrl(url: SitemapURL): SitemapValidationResult;

Returns { valid: boolean; errors: string[]; warnings: string[] }. Never throws.

toNextSitemap(urls)

import { toNextSitemap } from '@power-seo/sitemap';

function toNextSitemap(urls: SitemapURL[]): NextSitemapEntry[];

Converts a SitemapURL[] to the array format expected by Next.js App Router's app/sitemap.ts file convention. Invalid URLs (per validateSitemapUrl) are filtered out automatically. changefreq is mapped to changeFrequency.

FieldTypeDescription
urlstringAbsolute URL (loc)
lastModifiedDate | stringFrom lastmod (passed through as-is)
changeFrequencystringFrom changefreq
prioritynumberFrom priority

Types

TypeDescription
SitemapConfig{ hostname: string; urls: SitemapURL[]; maxUrlsPerSitemap?: number; outputDir?: string }
SitemapURLSingle URL entry — see field table below
SitemapImage{ loc: string; caption?: string; geoLocation?: string; title?: string; license?: string }
SitemapVideoVideo extension entry with thumbnailLoc, title, description, and optional fields
SitemapNews{ publication: { name: string; language: string }; publicationDate: string; title: string }
SitemapIndexConfig{ sitemaps: SitemapIndexEntry[] }
SitemapIndexEntry{ loc: string; lastmod?: string }
SitemapValidationResult{ valid: boolean; errors: string[]; warnings: string[] }

SitemapURL Fields

PropTypeDefaultDescription
locstringRequired. URL path (e.g. /about) or absolute URL. Hostname is prepended to relative paths.
lastmodstringLast modified date — ISO 8601 or YYYY-MM-DD
changefreq'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'Suggested crawl frequency
prioritynumber(no tag emitted)Priority 0.0–1.0. When omitted, no <priority> tag is written.
imagesSitemapImage[]Image extension entries — emits <image:image> blocks
videosSitemapVideo[]Video extension entries — emits <video:video> blocks
newsSitemapNewsNews extension entry — emits <news:news> block

Constants

ConstantValueDescription
MAX_URLS_PER_SITEMAP50_000Maximum URLs allowed per sitemap file (spec limit)
MAX_SITEMAP_SIZE_BYTES52_428_800Maximum sitemap file size in bytes (50 MB = 50 × 1024 × 1024)

Use Cases

  • Next.js App Router — generate sitemaps in app/sitemap.xml/route.ts at request time or build time
  • E-commerce catalogs — product image sitemaps with <image:image> for every listing; keep Google Images up to date
  • News publishers<news:news> extension for Google News sitemap submission
  • Multi-locale sites — separate sitemaps per locale with a unified sitemap index
  • Programmatic SEO — generate sitemaps for thousands of auto-generated pages with no memory overhead
  • Large sites — automatic splitting at 50,000 URLs per file with a generated index
  • Video platforms<video:video> extension with title, description, and thumbnail for video SEO
  • CI/CD pipelines — validate URL entries with validateSitemapUrl() as part of pull request checks

Architecture Overview

  • Pure TypeScript — no compiled binary, no native modules
  • Zero runtime dependencies — only @power-seo/core as a peer dependency
  • Framework-agnostic — works in any JavaScript environment that supports ES2020+
  • SSR compatible — safe to run in Next.js Server Components, Remix loaders, or Express handlers
  • Edge runtime safe — no fs, no path, no Node.js-specific APIs; runs in Cloudflare Workers, Vercel Edge, Deno
  • Synchronous generator streamingstreamSitemap() uses function* — no async overhead, no backpressure complexity
  • Smart namespace detectiongenerateSitemap() only declares image/video/news namespaces when actually used; streamSitemap() always includes all namespaces for simplicity
  • Tree-shakeable"sideEffects": false with named exports per function
  • Dual ESM + CJS — ships both formats via tsup for any bundler or require() usage

Supply Chain Security

  • No install scripts (postinstall, preinstall)
  • No runtime network access
  • No eval or dynamic code execution
  • CI-signed builds — all releases published via verified github.com/CyberCraftBD/power-seo workflow
  • Safe for SSR, Edge, and server environments

The @power-seo Ecosystem

All 17 packages are independently installable — use only what you need.

PackageInstallDescription
@power-seo/corenpm i @power-seo/coreFramework-agnostic utilities, types, validators, and constants
@power-seo/reactnpm i @power-seo/reactReact SEO components — meta, Open Graph, Twitter Card, breadcrumbs
@power-seo/metanpm i @power-seo/metaSSR meta helpers for Next.js App Router, Remix v2, and generic SSR
@power-seo/schemanpm i @power-seo/schemaType-safe JSON-LD structured data — 23 builders + 22 React components
@power-seo/content-analysisnpm i @power-seo/content-analysisYoast-style SEO content scoring engine with React components
@power-seo/readabilitynpm i @power-seo/readabilityReadability scoring — Flesch-Kincaid, Gunning Fog, Coleman-Liau, ARI
@power-seo/previewnpm i @power-seo/previewSERP, Open Graph, and Twitter/X Card preview generators
@power-seo/sitemapnpm i @power-seo/sitemapXML sitemap generation, streaming, index splitting, and validation
@power-seo/redirectsnpm i @power-seo/redirectsRedirect engine with Next.js, Remix, and Express adapters
@power-seo/linksnpm i @power-seo/linksLink graph analysis — orphan detection, suggestions, equity scoring
@power-seo/auditnpm i @power-seo/auditFull SEO audit engine — meta, content, structure, performance rules
@power-seo/imagesnpm i @power-seo/imagesImage SEO — alt text, lazy loading, format analysis, image sitemaps
@power-seo/ainpm i @power-seo/aiLLM-agnostic AI prompt templates and parsers for SEO tasks
@power-seo/analyticsnpm i @power-seo/analyticsMerge GSC + audit data, trend analysis, ranking insights, dashboard
@power-seo/search-consolenpm i @power-seo/search-consoleGoogle Search Console API — OAuth2, service account, URL inspection
@power-seo/integrationsnpm i @power-seo/integrationsSemrush and Ahrefs API clients with rate limiting and pagination
@power-seo/trackingnpm i @power-seo/trackingGA4, Clarity, PostHog, Plausible, Fathom — scripts + consent management

About CyberCraft Bangladesh

CyberCraft Bangladesh is a Bangladesh-based enterprise-grade software development and Full Stack SEO service provider company specializing in ERP system development, AI-powered SaaS and business applications, full-stack SEO services, custom website development, and scalable eCommerce platforms. We design and develop intelligent, automation-driven SaaS and enterprise solutions that help startups, SMEs, NGOs, educational institutes, and large organizations streamline operations, enhance digital visibility, and accelerate growth through modern cloud-native technologies.

Website GitHub npm Email

© 2026 CyberCraft Bangladesh · Released under the MIT License

Keywords

seo

FAQs

Package last updated on 28 Feb 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts