Powerfully flexible XML Sitemaps that integrate seamlessly, for Nuxt.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Server-side composables and utilities for runtime sitemap generation, URL processing, and event handler creation within the Nuxt server context.
// Available only in Nuxt server context
import { asSitemapUrl, defineSitemapEventHandler } from '#sitemap/server/composables';Type-safe converter for sitemap URL inputs in server context.
/**
* Type-safe converter for sitemap URL inputs
* Ensures proper typing for sitemap URL objects or strings
* @param url - URL input as SitemapUrlInput or generic object
* @returns Properly typed SitemapUrlInput
*/
function asSitemapUrl(url: SitemapUrlInput | Record<string, any>): SitemapUrlInput;Typed wrapper for H3 event handlers specifically for sitemap URL sources.
/**
* Typed event handler definition for sitemap URL sources
* Provides type safety for server endpoints that return sitemap URLs
*/
const defineSitemapEventHandler: typeof defineEventHandler<
EventHandlerRequest,
EventHandlerResponse<SitemapUrlInput[]>
>;Access to runtime sitemap configuration within server context.
/**
* Get runtime sitemap configuration with normalized filters
* @param e - Optional H3 event context
* @returns Frozen runtime configuration object
*/
function useSitemapRuntimeConfig(e?: H3Event): ModuleRuntimeConfig;
interface ModuleRuntimeConfig {
version: string;
isNuxtContentDocumentDriven: boolean;
sitemaps: Record<string, SitemapDefinition>;
autoI18n?: AutoI18nConfig;
isMultiSitemap: boolean;
isI18nMapped: boolean;
sitemapsPathPrefix: string | false;
cacheMaxAgeSeconds: number | false;
sitemapName: string;
excludeAppSources: true | AppSourceContext[];
sortEntries: boolean;
defaultSitemapsChunkSize: number | false;
xslColumns?: XslColumn[];
xslTips: boolean;
debug: boolean;
discoverImages: boolean;
discoverVideos: boolean;
autoLastmod: boolean;
xsl: string | false;
credits: boolean;
minify: boolean;
}XML-safe string escaping for content inserted into XML/XSL.
/**
* XML escape function for content inserted into XML/XSL
* Escapes special XML characters to prevent malformed XML
* @param str - String to escape
* @returns XML-safe escaped string
*/
function xmlEscape(str: string): string;Utilities for working with Nitro route rules in server context.
/**
* Remove query parameters from path
* @param path - URL path with potential query parameters
* @returns Path without query string
*/
function withoutQuery(path: string): string;
/**
* Create a matcher function for Nitro route rules
* @returns Function that matches paths against route rules
*/
function createNitroRouteRuleMatcher(): (pathOrUrl: string) => NitroRouteRules;Framework-agnostic utilities available in server context.
/**
* Pre-configured logger instance for sitemap operations
*/
const logger: ConsolaInstance;
/**
* Merge array items by a specific key, combining duplicate entries
* @param arr - Array of objects to merge
* @param key - Key to merge on
* @returns Array with merged items
*/
function mergeOnKey<T, K extends keyof T>(arr: T[], key: K): T[];
/**
* Split path for i18n locale extraction
* @param path - URL path
* @param locales - Array of valid locale codes
* @returns Tuple of [locale, path] or [null, path]
*/
function splitForLocales(path: string, locales: string[]): [string | null, string];
/**
* Normalize runtime filter inputs for pattern matching
* @param filters - Array of filter inputs
* @returns Normalized filters for runtime use
*/
function normalizeRuntimeFilters(filters: FilterInput[]): NormalizedFilter[];Usage Examples:
// server/api/_sitemap-urls.ts - Dynamic sitemap source
import { defineSitemapEventHandler, asSitemapUrl } from '#sitemap/server/composables';
export default defineSitemapEventHandler(async (event) => {
// Fetch dynamic data
const products = await $fetch('/api/products');
// Convert to sitemap URLs
return products.map(product => asSitemapUrl({
loc: `/products/${product.slug}`,
lastmod: product.updatedAt,
priority: product.featured ? 0.8 : 0.5,
changefreq: 'weekly'
}));
});
// server/api/custom-sitemap-handler.ts - Custom sitemap endpoint
import {
useSitemapRuntimeConfig,
xmlEscape,
defineSitemapEventHandler
} from '#sitemap/server/composables';
export default defineSitemapEventHandler(async (event) => {
const config = useSitemapRuntimeConfig(event);
// Use configuration for custom logic
if (!config.isMultiSitemap) {
return [];
}
// Safe XML content
const safeTitle = xmlEscape('Products & Services');
return [
asSitemapUrl({
loc: '/products',
lastmod: new Date(),
// Use escaped content in custom fields
_customField: safeTitle
})
];
});
// server/plugins/sitemap-source.ts - Server plugin for URL sources
import { logger, mergeOnKey } from '#sitemap/server/utils';
export default defineNitroPlugin(async (nitroApp) => {
// Use logger for debugging
logger.info('Initializing sitemap sources');
// Example of merging duplicate URLs by location
const urls = [
{ loc: '/page-1', priority: 0.5 },
{ loc: '/page-1', priority: 0.8 }, // Will be merged
{ loc: '/page-2', priority: 0.6 }
];
const mergedUrls = mergeOnKey(urls, 'loc');
// Result: [{ loc: '/page-1', priority: 0.8 }, { loc: '/page-2', priority: 0.6 }]
});
// server/api/i18n-urls.ts - i18n-aware URL generation
import {
splitForLocales,
defineSitemapEventHandler,
asSitemapUrl
} from '#sitemap/server/composables';
export default defineSitemapEventHandler(async (event) => {
const locales = ['en', 'fr', 'es'];
const path = '/blog/my-post';
const [locale, cleanPath] = splitForLocales('/fr/blog/my-post', locales);
// Result: ['fr', '/blog/my-post']
return [
asSitemapUrl({
loc: cleanPath,
_locale: locale
})
];
});
// server/middleware/route-rules.ts - Route rule matching
import { createNitroRouteRuleMatcher, withoutQuery } from '#sitemap/server/kit';
const routeRuleMatcher = createNitroRouteRuleMatcher();
export default defineEventHandler(async (event) => {
const url = getRequestURL(event);
const path = withoutQuery(url.pathname);
// Get matching route rules
const rules = routeRuleMatcher(path);
// Use rules for custom logic
if (rules.sitemap === false) {
// Skip this route in sitemap
return;
}
});Nitro Plugin Integration
Server composables work seamlessly with Nitro plugins for:
H3 Event Handler Context
All composables are designed to work within H3 event handlers, providing:
Runtime Configuration Access
The useSitemapRuntimeConfig provides access to:
Install with Tessl CLI
npx tessl i tessl/npm-nuxtjs--sitemap