Load and merge CloudCannon configuration files that have been split across multiple files.
This package brings the configuration loading functionality from CloudCannon into your local development environment. It's particularly useful for:
- Static site generators that need access to CloudCannon configuration at build time
- Custom integrations like the CloudCannon + Next.js starter that generate content schemas from CloudCannon config
- Development tooling that validates or processes CloudCannon configuration
- Node.js >= 22.6.0
npm install @cloudcannon/configuration-loaderimport { loadConfiguration } from '@cloudcannon/configuration-loader';
const result = await loadConfiguration('cloudcannon.config.yml');
console.log(result.config);That's it! The loadConfiguration function handles:
- Reading and parsing your configuration file (YAML or JSON)
- Finding all files matching
*_from_globpatterns - Merging everything into a single configuration object
For YAML files, install js-yaml:
npm install js-yamlThe loader will automatically detect and use it.
We don't bundle a YAML parser because:
- You likely already have one — most projects using CloudCannon configuration already have
js-yamlor similar installed for their build tooling - Keeps the package lightweight — no unnecessary dependencies if you only use JSON configs
- Flexibility — you can use any YAML parser via the
parseFileoption if you prefer a different one
const result = await loadConfiguration('cloudcannon.config.yml');
if (result.warnings.cycles.length > 0) {
console.warn('Circular references detected:', result.warnings.cycles);
}
if (result.warnings.arrayValues.length > 0) {
console.warn('Invalid array configs:', result.warnings.arrayValues);
}Loads and merges a CloudCannon configuration file with all its split configuration files.
const result = await loadConfiguration('cloudcannon.config.yml');configPath- Path to the CloudCannon configuration fileoptions.parseFile- Optional custom parser function for file contents
Lower-level API for custom implementations. Use this when you need full control over file loading and glob matching, or when running in a browser environment.
import { mergeConfiguration } from '@cloudcannon/configuration-loader/browser';
const result = await mergeConfiguration(config, {
findFilesMatchingGlobs: (globs) => /* your glob implementation */,
loadConfigFile: async (path) => /* your file loader */
});config- The base CloudCannon configuration objectoptions.findFilesMatchingGlobs- Function that takes an array of glob patterns and returns matching file pathsoptions.loadConfigFile- Async function that loads and parses a configuration file
A GlobResult object containing:
interface GlobResult {
// The merged configuration
config: Configuration;
// Warnings about potential issues
warnings: {
// Circular references in configuration
cycles: { path: string; chain: string[] }[];
// Files matched by multiple different glob keys
multipleGlobKeys: { path: string; type1: GlobTypeKey; type2: GlobTypeKey }[];
// Files containing arrays instead of objects
arrayValues: { path: string }[];
};
// All glob patterns found (for file watching)
globPatterns: string[];
// Mapping from file paths to their glob key type
pathsToGlobKey: Record<string, GlobTypeKey>;
// Mapping from glob key types to matched file paths
globKeyToPaths: Record<GlobTypeKey, Set<string>>;
}For browser environments (or anywhere without Node.js fs APIs), use the /browser entry point:
import { mergeConfiguration } from '@cloudcannon/configuration-loader/browser';
// You provide the implementations for glob matching and file loading
const result = await mergeConfiguration(config, {
findFilesMatchingGlobs: (globs) => {
// Your implementation - e.g., fetch from an API
return fetchMatchingFiles(globs);
},
loadConfigFile: async (filePath) => {
// Your implementation - e.g., fetch file contents
const response = await fetch(`/api/config/${filePath}`);
return response.json();
}
});This entry point exports only mergeConfiguration and the types, with no Node.js dependencies.
The loader processes the following *_from_glob keys:
| Key | Target | Description |
|---|---|---|
collections_config_from_glob |
collections_config |
Collection configurations |
schemas_from_glob |
schemas |
Schema configurations (within collections) |
_inputs_from_glob |
_inputs |
Input configurations |
_structures_from_glob |
_structures |
Structure configurations |
values_from_glob |
values |
Structure values |
_snippets_from_glob |
_snippets |
Snippet configurations |
_snippets_imports_from_glob |
_snippets_imports |
Snippet imports |
_snippets_templates_from_glob |
_snippets_templates |
Snippet templates |
_snippets_definitions_from_glob |
_snippets_definitions |
Snippet definitions |
_editables_from_glob |
_editables |
Editable region configurations |
Merged objects include a __source__ property indicating which file they came from:
const result = await loadConfiguration('cloudcannon.config.yml');
// Each merged input has a __source__ property
console.log(result.config._inputs?.title);
// { type: 'text', __source__: '/.cloudcannon/inputs/seo.yml' }# Install dependencies
npm install
# Run type checking
npm run typecheck
# Run tests
npm test
# Build type declarations
npm run buildThis package uses Node.js 22's native TypeScript support with type stripping (--experimental-strip-types). This means:
- TypeScript files run directly without compilation
- Type declarations are generated separately for package consumers
- No build step required for development
MIT