Configuration file handling, site metadata management, and plugin discovery utilities for Gatsby projects. These functions provide robust configuration parsing and management across different file formats and project structures.
Reads and manages Gatsby configuration files with support for both JavaScript and TypeScript formats.
/**
* Reads gatsby-config file (JS or TS), creates default if missing
* @param root - Site root directory path
* @returns Promise resolving to config file contents as string
* @throws Error if config file cannot be read or created
*/
function readConfigFile(root: string): Promise<string>;
/**
* Gets path to gatsby-config file, preferring TypeScript over JavaScript
* @param root - Site root directory path
* @returns Path to the configuration file (gatsby-config.ts or gatsby-config.js)
*/
function getConfigPath(root: string): string;Usage Examples:
import { readConfigFile, getConfigPath } from "gatsby-core-utils";
// Read configuration file contents
const configContent = await readConfigFile(process.cwd());
console.log("Config file contents:", configContent);
// Get path to config file
const configPath = getConfigPath("/path/to/gatsby-site");
console.log("Config file location:", configPath);
// Output: "/path/to/gatsby-site/gatsby-config.ts" (if exists)
// or "/path/to/gatsby-site/gatsby-config.js" (fallback)
// Use in build tools
const siteRoot = process.cwd();
const configPath = getConfigPath(siteRoot);
const configContent = await readConfigFile(siteRoot);
// Parse and modify configuration
const configModule = eval(configContent);
console.log("Site metadata:", configModule.siteMetadata);Discovers and lists all plugins configured in a Gatsby site.
/**
* Lists all plugins from gatsby-config.js
* @param options - Configuration object with site root path
* @returns Array of plugin names/resolve paths
*/
function listPlugins(options: { root: string }): Array<string>;Usage Examples:
import { listPlugins } from "gatsby-core-utils";
// Get all configured plugins
const plugins = listPlugins({ root: process.cwd() });
console.log("Configured plugins:", plugins);
// Output: ["gatsby-plugin-react-helmet", "gatsby-plugin-styled-components", ...]
// Filter plugins by type
const themePlugins = plugins.filter(plugin => plugin.includes("theme"));
const sourcePlugins = plugins.filter(plugin => plugin.includes("source"));
// Validate plugin configuration
for (const plugin of plugins) {
try {
require.resolve(plugin);
console.log(`✓ ${plugin} - installed`);
} catch (error) {
console.log(`✗ ${plugin} - missing`);
}
}
// Generate plugin report
const pluginReport = {
total: plugins.length,
official: plugins.filter(p => p.startsWith("gatsby-")).length,
community: plugins.filter(p => !p.startsWith("gatsby-")).length,
themes: plugins.filter(p => p.includes("theme")).length
};
console.log("Plugin report:", pluginReport);Manages internal site metadata and configuration updates.
/**
* Interface for site metadata structure
*/
interface ISiteMetadata {
sitePath: string;
name?: string;
pid?: number;
lastRun?: number;
}
/**
* Retrieves internal site metadata
* @param sitePath - Path to the Gatsby site
* @returns Promise resolving to metadata object or null if not found
*/
function getInternalSiteMetadata(sitePath: string): Promise<ISiteMetadata | null>;
/**
* Updates internal site metadata
* @param metadata - Metadata object to store
* @param merge - Whether to merge with existing data (default: true)
* @returns Promise resolving when update is complete
*/
function updateInternalSiteMetadata(
metadata: ISiteMetadata,
merge?: boolean
): Promise<void>;
/**
* Legacy alias for updateInternalSiteMetadata (deprecated in v5)
* @param metadata - Metadata object to store
* @param merge - Whether to merge with existing data (default: true)
* @returns Promise resolving when update is complete
*/
function updateSiteMetadata(
metadata: ISiteMetadata,
merge?: boolean
): Promise<void>;
/**
* Adds a field to gatsby-config.js siteMetadata
* @param options - Object with root directory path
* @param field - Object with field name and value to add
* @returns Promise resolving when field is added
*/
function addFieldToMinimalSiteMetadata(
options: { root: string },
field: { name: string; value: string }
): Promise<void>;Usage Examples:
import {
getInternalSiteMetadata,
updateInternalSiteMetadata,
addFieldToMinimalSiteMetadata
} from "gatsby-core-utils";
// Retrieve site metadata
const metadata = await getInternalSiteMetadata(process.cwd());
if (metadata) {
console.log("Site name:", metadata.name);
console.log("Last run:", new Date(metadata.lastRun));
console.log("Process ID:", metadata.pid);
}
// Update site metadata
await updateInternalSiteMetadata({
sitePath: process.cwd(),
name: "My Gatsby Site",
pid: process.pid,
lastRun: Date.now()
});
// Merge with existing metadata
await updateInternalSiteMetadata({
sitePath: process.cwd(),
lastRun: Date.now()
}, true); // merge=true preserves existing fields
// Add field to gatsby-config.js siteMetadata
await addFieldToMinimalSiteMetadata(
{ root: process.cwd() },
{ name: "buildDate", value: new Date().toISOString() }
);
// Results in gatsby-config.js:
// module.exports = {
// siteMetadata: {
// buildDate: "2023-10-15T10:30:00.000Z"
// }
// }Manages persistent configuration storage using the Configstore library.
/**
* Returns a singleton Configstore instance for Gatsby configuration
* @returns Configstore instance with global configuration path
*/
function getConfigStore(): Configstore;Usage Examples:
import { getConfigStore } from "gatsby-core-utils";
// Get global configuration store
const config = getConfigStore();
// Store user preferences
config.set("telemetry.enabled", false);
config.set("user.defaultTemplate", "gatsby-starter-default");
config.set("build.concurrency", 4);
// Retrieve configuration values
const telemetryEnabled = config.get("telemetry.enabled"); // false
const defaultTemplate = config.get("user.defaultTemplate");
const buildConcurrency = config.get("build.concurrency");
// Store complex configuration objects
config.set("deployTargets", {
netlify: { enabled: true, buildCommand: "gatsby build" },
vercel: { enabled: false, buildCommand: "npm run build" }
});
// Get all configuration
const allConfig = config.all;
console.log("Full configuration:", allConfig);
// Clear configuration
config.clear();Detects the installed Gatsby version for compatibility checks.
/**
* Gets the installed Gatsby version from package.json
* @returns Version string or empty string if not found
*/
function getGatsbyVersion(): string;Usage Examples:
import { getGatsbyVersion } from "gatsby-core-utils";
// Get Gatsby version
const version = getGatsbyVersion();
console.log("Gatsby version:", version); // "5.2.0"
// Version-based feature detection
const majorVersion = parseInt(version.split('.')[0]);
if (majorVersion >= 4) {
console.log("Using Gatsby v4+ features");
enableSSRFeatures();
} else {
console.log("Using legacy Gatsby features");
enableLegacyFeatures();
}
// Compatibility warnings
if (version && semver.lt(version, "4.0.0")) {
console.warn("This plugin requires Gatsby v4.0.0 or higher");
}
// Plugin compatibility matrix
const compatibility = {
"gatsby-plugin-image": majorVersion >= 3,
"gatsby-plugin-sharp": majorVersion >= 2,
"gatsby-transformer-remark": true // All versions
};import { readConfigFile, getConfigPath } from "gatsby-core-utils";
// Create default configuration if missing
async function ensureConfigFile(root: string) {
try {
const configContent = await readConfigFile(root);
return configContent;
} catch (error) {
// Config file doesn't exist, create default
const defaultConfig = `
module.exports = {
siteMetadata: {
title: "My Gatsby Site",
description: "A site built with Gatsby"
},
plugins: [
"gatsby-plugin-react-helmet",
"gatsby-plugin-image",
"gatsby-plugin-sharp"
]
};
`.trim();
const configPath = getConfigPath(root);
await fs.writeFile(configPath, defaultConfig);
return defaultConfig;
}
}import { listPlugins } from "gatsby-core-utils";
import { promises as fs } from "fs";
import path from "path";
async function validatePluginConfiguration(root: string) {
const plugins = listPlugins({ root });
const validationResults = [];
for (const plugin of plugins) {
const result = { plugin, status: 'unknown', issues: [] };
try {
// Check if plugin is installed
const pluginPath = require.resolve(plugin, { paths: [root] });
result.status = 'installed';
// Check if plugin has gatsby-node.js
const gatsbyNodePath = path.join(path.dirname(pluginPath), 'gatsby-node.js');
const hasGatsbyNode = await fs.access(gatsbyNodePath).then(() => true).catch(() => false);
if (!hasGatsbyNode) {
result.issues.push('No gatsby-node.js found');
}
// Check version compatibility
const packageJsonPath = path.join(path.dirname(pluginPath), 'package.json');
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
if (packageJson.peerDependencies && packageJson.peerDependencies.gatsby) {
const requiredGatsbyVersion = packageJson.peerDependencies.gatsby;
const installedVersion = getGatsbyVersion();
// Simple version check (would use semver in real implementation)
if (!semver.satisfies(installedVersion, requiredGatsbyVersion)) {
result.issues.push(`Gatsby version mismatch: requires ${requiredGatsbyVersion}, have ${installedVersion}`);
}
}
} catch (error) {
result.status = 'missing';
result.issues.push(`Not installed: ${error.message}`);
}
validationResults.push(result);
}
return validationResults;
}import {
getInternalSiteMetadata,
updateInternalSiteMetadata,
addFieldToMinimalSiteMetadata
} from "gatsby-core-utils";
class SiteMetadataManager {
constructor(private sitePath: string) {}
async syncBuildMetadata() {
const buildInfo = {
buildTime: Date.now(),
nodeVersion: process.version,
gatsbyVersion: getGatsbyVersion(),
environment: process.env.NODE_ENV
};
// Update internal metadata
await updateInternalSiteMetadata({
sitePath: this.sitePath,
lastRun: buildInfo.buildTime,
pid: process.pid
});
// Add build info to site metadata
for (const [key, value] of Object.entries(buildInfo)) {
await addFieldToMinimalSiteMetadata(
{ root: this.sitePath },
{ name: key, value: String(value) }
);
}
}
async getBuildHistory() {
const metadata = await getInternalSiteMetadata(this.sitePath);
return {
lastBuild: metadata?.lastRun ? new Date(metadata.lastRun) : null,
processId: metadata?.pid,
siteName: metadata?.name
};
}
}
// Usage
const metadataManager = new SiteMetadataManager(process.cwd());
await metadataManager.syncBuildMetadata();
const history = await metadataManager.getBuildHistory();Configuration management functions handle various error scenarios:
readConfigFile() creates default configurationlistPlugins() handles plugins that can't be resolvedimport { readConfigFile, listPlugins } from "gatsby-core-utils";
async function safeConfigurationLoad(root: string) {
try {
const configContent = await readConfigFile(root);
const plugins = listPlugins({ root });
return { configContent, plugins, errors: [] };
} catch (error) {
console.error("Configuration load failed:", error.message);
// Attempt recovery
const errors = [error.message];
let configContent = null;
let plugins = [];
try {
plugins = listPlugins({ root });
} catch (pluginError) {
errors.push(`Plugin discovery failed: ${pluginError.message}`);
}
return { configContent, plugins, errors };
}
}Configuration management is fundamental to Gatsby's operation:
Utilities for managing Gatsby page data files and paths.
/**
* Converts root path "/" to "index" for consistent page data paths
* @param pagePath - Page path to fix
* @returns Fixed page path ("/" becomes "index")
*/
function fixedPagePath(pagePath: string): string;
/**
* Generates the file path for page-data.json files
* @param publicDir - Public directory path
* @param pagePath - Page path
* @returns Full path to page-data.json file
*/
function generatePageDataPath(publicDir: string, pagePath: string): string;Utilities for managing HTML file generation and cleanup.
/**
* Generates HTML file path, adding index.html for directories
* @param dir - Base directory
* @param outputPath - Output path
* @returns Full HTML file path
*/
function generateHtmlPath(dir: string, outputPath: string): string;
/**
* Removes HTML file for a page
* @param options - Object with publicDir path
* @param pagePath - Page path to remove
* @returns Promise resolving when file is removed
*/
function remove(options: { publicDir: string }, pagePath: string): Promise<void>;Utilities for parsing component paths with content file queries (used by gatsby-plugin-mdx).
/**
* Splits component path URI containing content file query parameter
* @param componentPath - Component path with optional query
* @returns Array with [componentPath] or [componentPath, contentFilePath]
*/
function splitComponentPath(componentPath: string): Array<string>;
/**
* Gets path to the layout component (JS file)
* @param componentPath - Full component path
* @returns Path to JS component
*/
function getPathToLayoutComponent(componentPath: string): string;
/**
* Gets path to content file or falls back to JS component
* @param componentPath - Full component path
* @returns Path to content file or JS component
*/
function getPathToContentComponent(componentPath: string): string;Usage Examples:
import {
fixedPagePath,
generatePageDataPath,
generateHtmlPath,
splitComponentPath,
getPathToLayoutComponent,
getPathToContentComponent
} from "gatsby-core-utils";
// Page data path generation
const dataPath = generatePageDataPath("./public", "/about/");
console.log(dataPath); // "./public/page-data/about/page-data.json"
const rootDataPath = generatePageDataPath("./public", "/");
console.log(rootDataPath); // "./public/page-data/index/page-data.json"
// HTML path generation
const htmlPath = generateHtmlPath("./public", "/about");
console.log(htmlPath); // "./public/about/index.html"
// Component path parsing (gatsby-plugin-mdx v4+)
const componentWithContent = "src/pages/blog.js?__contentFilePath=/content/post.mdx";
const [layoutPath, contentPath] = splitComponentPath(componentWithContent);
console.log(layoutPath); // "src/pages/blog.js"
console.log(contentPath); // "/content/post.mdx"
const layoutComponent = getPathToLayoutComponent(componentWithContent);
console.log(layoutComponent); // "src/pages/blog.js"
const contentComponent = getPathToContentComponent(componentWithContent);
console.log(contentComponent); // "/content/post.mdx"Configuration management is fundamental to Gatsby's operation: