Gatsby plugin that automatically creates XML sitemaps for your site during the production build process
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Helper functions for site URL resolution, page processing, filtering, and serialization that can be customized or used independently.
/**
* Removes trailing slash from path except for root path
* @param path - Path string to process
* @returns Path without trailing slash, except for root '/'
*/
function withoutTrailingSlash(path: string): string;Usage Example:
withoutTrailingSlash('/about/'); // Returns: '/about'
withoutTrailingSlash('/'); // Returns: '/' (unchanged)
withoutTrailingSlash('/contact'); // Returns: '/contact' (unchanged)/**
* Properly handles prefixing relative path with site domain and pathPrefix
* @param options - Path prefixing options
* @param options.url - Relative URL to prefix
* @param options.siteUrl - Site domain URL
* @param options.pathPrefix - Optional path prefix
* @returns Complete URL with proper prefixing
*/
function prefixPath({ url, siteUrl, pathPrefix = '' }: {
url: string;
siteUrl: string;
pathPrefix?: string;
}): string;Usage Example:
prefixPath({
url: '/about',
siteUrl: 'https://example.com',
pathPrefix: '/blog'
});
// Returns: 'https://example.com/blog/about'/**
* Extracts site URL from GraphQL query data
* @param data - Results of the GraphQL query
* @returns Site URL string
* @throws Error if siteUrl not found in data.site.siteMetadata.siteUrl
*/
function resolveSiteUrl(data: any): string;Expected Data Structure:
const data = {
site: {
siteMetadata: {
siteUrl: 'https://example.com'
}
}
};Usage Example:
// Used internally by the plugin, or in custom resolveSiteUrl function
try {
const siteUrl = resolveSiteUrl(queryData);
console.log(siteUrl); // 'https://example.com'
} catch (error) {
console.error('Site URL not found in query data');
}/**
* Extracts page path from page object
* @param page - Page object with path property
* @returns Page path without domain or protocol
* @throws Error if path property not found on page
*/
function resolvePagePath(page: any): string;Expected Page Structure:
const page = {
path: '/about-us',
// ... other page properties
};Usage Example:
const page = { path: '/contact', id: 'page-1' };
const path = resolvePagePath(page); // Returns: '/contact'/**
* Extracts pages array from GraphQL query data
* @param data - Results of the GraphQL query
* @returns Array of page objects
* @throws Error if pages not found at data.allSitePage.nodes
*/
function resolvePages(data: any): any[];Expected Data Structure:
const data = {
allSitePage: {
nodes: [
{ path: '/about' },
{ path: '/contact' },
// ... more pages
]
}
};Usage Example:
const pages = resolvePages(queryData);
console.log(pages); // [{ path: '/about' }, { path: '/contact' }]/**
* Default page filtering function using minimatch for glob patterns
* @param page - Page object to check
* @param excludedRoute - Exclude pattern (must be string)
* @param tools - Filtering utilities
* @param tools.minimatch - Glob pattern matching function
* @param tools.withoutTrailingSlash - Trailing slash removal function
* @param tools.resolvePagePath - Page path extraction function
* @returns true to exclude page, false to include
* @throws Error if excludedRoute is not a string
*/
function defaultFilterPages(
page: any,
excludedRoute: string,
tools: {
minimatch: (path: string, pattern: string) => boolean;
withoutTrailingSlash: (path: string) => string;
resolvePagePath: (page: any) => string;
}
): boolean;Usage Example:
const shouldExclude = defaultFilterPages(
{ path: '/admin/dashboard' },
'/admin/*',
{ minimatch, withoutTrailingSlash, resolvePagePath }
);
// Returns: true (page should be excluded)/**
* Main filtering function that applies both default and custom filters
* @param options - Filtering options
* @param options.allPages - Array of all pages to filter
* @param options.filterPages - Custom filtering function
* @param options.excludes - Array of exclude patterns
* @returns Object with filtered pages and log messages
*/
function pageFilter({
allPages,
filterPages,
excludes
}: {
allPages: any[];
filterPages: (page: any, excludedRoute: any, tools: FilterTools) => boolean;
excludes: any[];
}): {
filteredPages: any[];
messages: string[];
};Default Excludes (always applied):
/dev-404-page/404/404.html/offline-plugin-app-shell-fallbackUsage Example:
const { filteredPages, messages } = pageFilter({
allPages: [
{ path: '/about' },
{ path: '/404' },
{ path: '/admin/users' }
],
filterPages: defaultFilterPages,
excludes: ['/admin/*']
});
console.log(filteredPages); // [{ path: '/about' }]
console.log(messages); // ['Default filter excluded page /404', 'Custom filtering excluded page /admin/users']/**
* Default serialization function for sitemap entries
* @param page - Page object to serialize
* @param tools - Serialization utilities
* @param tools.resolvePagePath - Page path extraction function
* @returns Sitemap entry object
*/
function serialize(
page: any,
tools: { resolvePagePath: (page: any) => string }
): {
url: string;
changefreq: 'daily';
priority: 0.7;
};Usage Example:
const entry = serialize(
{ path: '/about' },
{ resolvePagePath }
);
console.log(entry);
// {
// url: '/about',
// changefreq: 'daily',
// priority: 0.7
// }Note: Google ignores changefreq and priority values. Focus on accurate lastmod dates in custom serialize functions.
/**
* Prefix for all reporter messages from the plugin
*/
const REPORTER_PREFIX = '[gatsby-plugin-sitemap]:';Usage Example:
reporter.verbose(`${REPORTER_PREFIX} Processing ${pages.length} pages`);
// Outputs: [gatsby-plugin-sitemap]: Processing 25 pages// For environment-based URLs
const customResolveSiteUrl = (data) => {
return process.env.NODE_ENV === 'production'
? 'https://mysite.com'
: 'http://localhost:8000';
};// Include last modified date
const customSerialize = ({ path, modifiedGmt }, { resolvePagePath }) => ({
url: resolvePagePath({ path }),
lastmod: modifiedGmt,
// Omit changefreq and priority as Google ignores them
});// Custom filtering with complex logic
const customFilterPages = (page, excludedRoute, { resolvePagePath }) => {
const path = resolvePagePath(page);
if (typeof excludedRoute === 'string') {
return minimatch(path, excludedRoute);
}
// Handle custom exclude objects
if (excludedRoute.pattern) {
return minimatch(path, excludedRoute.pattern) && excludedRoute.condition(page);
}
return false;
};