// Advanced sitemap generation utilities
import { MetadataRoute } from 'next';
import { getBaseUrl, getAllRoutes } from './sitemap-utils';
// Generate XML sitemap manually (alternative to Next.js built-in)
export function generateSitemapXML(): string {
const baseUrl = getBaseUrl();
const routes = getAllRoutes();
const urlEntries = routes
.map((route) => {
const url = `${baseUrl}${route.url}`;
const lastmod =
route.lastModified?.toISOString().split('T')[0] ||
new Date().toISOString().split('T')[0];
const changefreq = route.changeFrequency || 'monthly';
const priority = route.priority || 0.5;
return `
${url}
${lastmod}
${changefreq}
${priority}
`;
})
.join('\n');
return `
${urlEntries}
`;
}
// Generate sitemap index for multiple sitemaps
export function generateSitemapIndex(): string {
const baseUrl = getBaseUrl();
const now = new Date().toISOString();
return `
${baseUrl}/sitemap.xml
${now}
`;
}
// Validate sitemap URLs
export function validateSitemapUrls(): { valid: boolean; errors: string[] } {
const routes = getAllRoutes();
const errors: string[] = [];
routes.forEach((route, index) => {
// Check for valid URL format
if (!route.url.startsWith('/') && route.url !== '') {
errors.push(`Route ${index}: URL should start with '/' or be empty for root`);
}
// Check priority range
if (route.priority && (route.priority < 0 || route.priority > 1)) {
errors.push(`Route ${index}: Priority should be between 0 and 1`);
}
// Check for duplicate URLs
const duplicates = routes.filter((r) => r.url === route.url);
if (duplicates.length > 1) {
errors.push(`Route ${index}: Duplicate URL found: ${route.url}`);
}
});
return {
valid: errors.length === 0,
errors,
};
}
// Get sitemap statistics
export function getSitemapStats() {
const routes = getAllRoutes();
const baseUrl = getBaseUrl();
return {
totalUrls: routes.length,
baseUrl,
lastGenerated: new Date().toISOString(),
routesByPriority: {
high: routes.filter((r) => (r.priority || 0) >= 0.8).length,
medium: routes.filter((r) => (r.priority || 0) >= 0.5 && (r.priority || 0) < 0.8)
.length,
low: routes.filter((r) => (r.priority || 0) < 0.5).length,
},
routesByChangeFreq: routes.reduce(
(acc, route) => {
const freq = route.changeFrequency || 'monthly';
acc[freq] = (acc[freq] || 0) + 1;
return acc;
},
{} as Record,
),
};
}