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;
};