Official SDK and CLI tools for LeadCMS - framework-agnostic content management for static site generators
npm install @leadcms/sdkA comprehensive, framework-agnostic SDK and CLI tools for integrating with LeadCMS. Provides clean access to your LeadCMS content through simple JavaScript/TypeScript functions that work with any framework or static site generator.
``bash`
npm install --save-dev @leadcms/sdk
`bash`
npm install @leadcms/sdk
`bash`
npm install -g @leadcms/sdk
Development Dependency (--save-dev) - Recommended for:
- โ
Static Site Generators (Next.js, Astro, Gatsby, Nuxt)
- โ
Build-time content fetching and processing
- โ
Static route generation
- โ
Content pre-processing during build
Production Dependency (--save) - Use when you need:
- ๐ Server-Side Rendering (SSR) with dynamic content
- ๐ API routes that fetch LeadCMS content at runtime
- ๐ Live preview functionality in production
- ๐ Runtime content loading and processing
Global Installation (-g) - Best for:
- ๐ ๏ธ CLI commands across multiple projects
- ๐ ๏ธ Project initialization and setup
- ๐ ๏ธ Content fetching and Docker template generation
Get started with LeadCMS in 3 simple steps:
bash
npx leadcms init
`
This will:
- Connect to your LeadCMS instance
- Detect available entity types (content, media, comments)
- Create configuration files (.env and optionally leadcms.config.json)$3
`bash
npx leadcms login
`
- LeadCMS v1.2.88+: Automatic device authentication via browser
- Older versions: Guided manual token extraction
- Saves your API token securely to .envSkip this step if you only need read-only access to public content.
$3
`bash
npx leadcms pull
`
Downloads all content, media, and comments to your local project.That's it! You're ready to use LeadCMS content in your application. See Usage Examples below.
CI/CD Integration

The LeadCMS SDK includes comprehensive CI/CD workflows for GitHub Actions that provide:
$3
- Multi-Node Support: Tests run on Node.js 18, 20, and 22
- Coverage Reports: Automatic coverage reporting with visual coverage diffs on PRs
- Test Results: Interactive test results displayed directly in GitHub Actions
- JUnit XML: Structured test output for integration with external tools$3
- LCOV Reports: Line and branch coverage tracking
- PR Comments: Automatic coverage comments on pull requests showing coverage changes
- Coverage Artifacts: HTML coverage reports archived for 30 days
- Multiple Formats: Coverage available in LCOV, HTML, and Clover formats$3
- TypeScript Compilation: Ensures type safety across all Node.js versions
- Package Validation: Verifies package structure and CLI functionality
- Docker Template Testing: Validates generated Docker configurations$3
If you're using this SDK in your own project, you can add similar testing workflows:
`yaml
.github/workflows/test.yml
name: Testson: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm test
`$3
`bash
Run all tests
npm testRun tests with coverage
npm run test:coverageRun tests in watch mode
npm run test:watch
`$3
The SDK maintains high test coverage with comprehensive unit tests covering:
- ๐ Content retrieval and parsing
- ๐ Multi-language support and translations
- ๐ Draft content handling and user-specific overrides
- ๐๏ธ Build-time optimizations and caching
- ๐ง Configuration management and validation
- ๐ Push/Pull synchronization with conflict detection
- ๐ฅ๏ธ CLI command functionality with mocked API responses
$3
For testing CLI commands locally without a real LeadCMS instance, use the built-in mock data service:
`bash
Enable mock mode and test status command
LEADCMS_USE_MOCK=true LEADCMS_CONTENT_DIR=./test-content npx leadcms statusTest with different mock scenarios
LEADCMS_USE_MOCK=true LEADCMS_MOCK_SCENARIO=hasConflicts npx leadcms status
LEADCMS_USE_MOCK=true LEADCMS_MOCK_SCENARIO=mixedOperations npx leadcms push --dry-run
`Available Mock Scenarios:
-
allNew - Local content that doesn't exist remotely (default)
- noChanges - All content is in sync
- hasConflicts - Remote content is newer than local
- hasUpdates - Local content is newer than remote
- mixedOperations - Mix of new, updated, and conflicted content
- missingContentTypes - Content with unknown typesMock Mode Activation:
-
NODE_ENV=test - Automatically uses mock mode
- LEADCMS_USE_MOCK=true - Force mock modeThe data service abstraction automatically handles switching between real API calls and mock data based on your environment, providing seamless testing without external dependencies.
Configuration
LeadCMS SDK supports multiple configuration methods in order of priority:
> ๐ Quick Start: Run
npx leadcms init for an interactive setup wizard that handles everything!$3
For security reasons, it's best to keep sensitive credentials as environment variables:
`bash
Required
LEADCMS_URL=your-leadcms-instance-urlOptional - API key for authenticated access
Omit this for public-only mode (published content only)
LEADCMS_API_KEY=your-api-keyOptional - can also be set via environment variables
LEADCMS_DEFAULT_LANGUAGE=en
LEADCMS_CONTENT_DIR=.leadcms/content
LEADCMS_MEDIA_DIR=public/media
LEADCMS_ENABLE_DRAFTS=trueNext.js users can also use:
NEXT_PUBLIC_LEADCMS_URL=your-leadcms-instance-url
NEXT_PUBLIC_LEADCMS_DEFAULT_LANGUAGE=en
`> ๏ฟฝ Security Note: The SDK uses a security-first approach - all read operations (content, comments, media sync) are performed WITHOUT authentication, ensuring only public data is retrieved. API keys are only used for write operations. See Public API Mode Guide for details.
$3
Create a
leadcms.config.json file only if you need to override default settings like contentDir, mediaDir, or defaultLanguage:`bash
Initialize configuration file
npx leadcms init
``json
{
"defaultLanguage": "en",
"contentDir": ".leadcms/content",
"mediaDir": "public/media",
"enableDrafts": false
}
`> Security Note: Avoid putting
url and apiKey in config files. Environment variables are safer and work better with deployment platforms.$3
For advanced use cases, you can configure the SDK programmatically:
`typescript
import { configure } from '@leadcms/sdk';configure({
url: 'https://your-leadcms-instance.com',
apiKey: 'your-api-key',
defaultLanguage: 'en',
contentDir: '.leadcms/content',
mediaDir: 'public/media',
enableDrafts: false
});
`> Best Practice: Use environment variables for
url and apiKey, and programmatic configuration only for project-specific overrides.$3
-
url - Your LeadCMS instance URL (required, best as env var)
- apiKey - Your LeadCMS API key (optional, omit for public-only mode, best as env var when used)
- defaultLanguage - Default language code (default: "en")
- contentDir - Directory for downloaded content (default: ".leadcms/content")
- mediaDir - Directory for media files (default: "public/media")
- enableDrafts - Enable draft content support (default: false, requires API key)CLI Usage
$3
`bash
npx leadcms version
or
npx leadcms -v
or
npx leadcms --version
`$3
`bash
npx leadcms init
`Interactive setup wizard that:
1. Connects to your LeadCMS instance - Validates URL and checks for existing authentication
2. Fetches configuration - Retrieves default language and available languages from public
/api/config endpoint
3. Configures directories - Sets content and media directories (defaults: .leadcms/content, public/media)
4. Creates environment file - Saves configuration to .env
5. Creates config file - Only if you use non-default directories (keeps your project clean!)Note: The
/api/config endpoint is public and works without authentication. For write operations and private content, run leadcms login after initialization.$3
`bash
npx leadcms login
`Authenticates with your LeadCMS instance:
- Device Authentication (LeadCMS v1.2.88+) - Opens a browser link for secure authentication
- Manual Token (older versions) - Guides you through extracting an API token
- Saves token - Automatically stores the token in your
.env fileWhen to use:
- After running
leadcms init if you need write access
- To update an expired or invalid token
- When switching between LeadCMS instancesExample session:
`
๐ LeadCMS SDK InitializationEnter your LeadCMS URL: https://your-instance.leadcms.ai
๐ Authentication Setup
Authentication is optional and can be skipped for most use cases.
โข Without authentication: You can pull content and build your site (read-only access)
โข With authentication: You can also push content changes back to LeadCMS
โข You can always authenticate later by running: leadcms login
Would you like to authenticate now? (Y/n): n
โน๏ธ Skipping authentication. Continuing in read-only mode.
You can run "leadcms login" later to authenticate.
๐ Connecting to LeadCMS...
โ
Connected successfully!
๐ Available languages:
1. English (United States) [en-US] (default)
2. Russian (Russia) [ru-RU]
Default language code [en-US]:
โ Using default language: en-US
๐ฆ Supported entity types:
โ Content
โ Media
โ Comments
Content directory [.leadcms/content]:
Media directory [public/media]:
Comments directory [.leadcms/comments]:
๐ Creating configuration files...
โ
Updated .env
โน๏ธ Using default directories, no leadcms.config.json needed.
โจ Configuration complete!
Next steps:
1. Run: npx leadcms login (for write access and private content)
2. Run: npx leadcms pull (to download content)
3. Start using LeadCMS content in your project
`The wizard creates:
-
.env (or .env if exists) with LEADCMS_URL, LEADCMS_DEFAULT_LANGUAGE, and optionally LEADCMS_API_KEY
- leadcms.config.json only if custom directories are specifiedAnonymous Mode: Perfect for static sites that only need public content. Omit the API key to skip authentication entirely.
$3
`bash
npx leadcms docker
Creates Docker files for production and preview deployments
`$3
The CLI supports several focused pull commands so you can sync exactly what you need.
`bash
Pull everything (content, media, comments)
npx leadcms pullPull only content (no media or comments)
npx leadcms pull-contentPull only media files
npx leadcms pull-mediaPull only comments
npx leadcms pull-comments
`> Note:
npx leadcms fetch is still supported as an alias for backward compatibility.What each command does:
-
npx leadcms pull - Syncs content, media and comments into your project using the configured directories. Updates incremental sync tokens so subsequent runs are faster.
- npx leadcms pull-content - Downloads only content entities (MDX/JSON files) and updates local metadata.
- npx leadcms pull-media - Downloads media files to your mediaDir (e.g., public/media). Use this when you changed media or want to refresh assets separately from content.
- npx leadcms pull-comments - Downloads comments to the comments directory (e.g., .leadcms/comments/). Useful when you only need comment updates.> Note: The CLI uses incremental sync tokens to avoid re-downloading unchanged items where supported by the LeadCMS API.
$3
`bash
npx leadcms push [options]
`Push your local content changes to LeadCMS. This command will:
- Analyze local MDX/JSON files and compare with remote content
- Detect new content, updates, and conflicts using
updatedAt timestamps
- Prompt for confirmation before making changes
- Support for creating missing content types automatically
- Update local files with remote metadata (id, createdAt, updatedAt) after syncOptions:
-
--force - Override remote changes (skip conflict check)
Content frontmatter / metadata (required and optional fields):
`yaml
---
type: "article" # required: Content type (must exist in LeadCMS)
title: "Article Title" # required: Content title
slug: "article-slug" # required: URL slug (unique per locale)
language: "en" # required: Content language
publishedAt: "2024-10-29T10:00:00Z" # optional: Publication date (omit to create a draft or schedule a future publish)
updatedAt: "2024-10-29T10:00:00Z" # optional: maintained by the server; do not set for new content
---
`Notes:
-
publishedAt is optional. Omitting it is a valid way to create draft or scheduled content depending on your LeadCMS workflow.
- updatedAt is typically set and maintained by the LeadCMS server after content is created or updated. The SDK will use updatedAt when present for conflict detection, but you should not rely on it being set for brand-new local files.$3
`bash
npx leadcms status
`Shows the current sync status between local and remote content without making any changes.
Note: The
status command currently only supports content. Media and comments do not have sync status checking yet.$3
`bash
npx leadcms watch
`Framework Integration
The SDK provides framework-agnostic data access. Most frameworks use it as a development dependency for build-time static generation:
`typescript
// Next.js Static Generation (Build-time only - devDependency)
export function generateStaticParams() {
// This runs at BUILD TIME, not runtime
const routes = getAllContentRoutes();
return routes.map(route => ({
slug: route.slugParts,
...(route.isDefaultLocale ? {} : { locale: route.locale })
}));
}// Astro Static Generation (Build-time only - devDependency)
export function getStaticPaths() {
// This runs at BUILD TIME, not runtime
const routes = getAllContentRoutes();
return routes.map(route => ({
params: { slug: route.slug },
props: { locale: route.locale, path: route.path }
}));
}
// Gatsby Static Generation (Build-time only - devDependency)
exports.createPages = async ({ actions }) => {
const { createPage } = actions;
const routes = getAllContentRoutes();
routes.forEach(route => {
createPage({
path: route.path,
component: path.resolve('./src/templates/content.js'),
context: { slug: route.slug, locale: route.locale }
});
});
};
// Runtime Usage Examples (Production dependency required)
// Next.js API Route (Runtime)
import { getCMSContentBySlugForLocale } from '@leadcms/sdk';
export async function GET(request) {
// This runs at REQUEST TIME, needs production dependency
const content = getCMSContentBySlugForLocale('about', 'en');
return Response.json(content);
}
// Express.js Server (Runtime)
app.get('/api/content/:slug', (req, res) => {
// This runs at REQUEST TIME, needs production dependency
const content = getCMSContentBySlugForLocale(req.params.slug, 'en');
res.json(content);
});
`API Reference
$3
Get content from your LeadCMS instance:
`typescript
import {
getCMSContentBySlugForLocale,
getAllContentSlugsForLocale,
getAllContentRoutes
} from '@leadcms/sdk';// Get single content item
const content = getCMSContentBySlugForLocale('about-us', 'en');
// Get all content slugs
const slugs = getAllContentSlugsForLocale('en');
// Get all routes for static generation
const routes = getAllContentRoutes();
`๐ See Content Management Guide for complete API documentation, framework integration examples, and advanced features.
#### Preview Mode (Zero Configuration)
The SDK automatically detects preview slugs and enables draft content access without requiring explicit configuration:
`typescript
import { getCMSContentBySlugForLocale } from '@leadcms/sdk';// Normal slug - only returns published content
const published = getCMSContentBySlugForLocale('home', 'en');
// Returns: null if content has no publishedAt
// Preview slug with GUID - automatically enables draft access
const preview = getCMSContentBySlugForLocale(
'home-550e8400-e29b-41d4-a716-446655440000',
'en'
);
// Returns: draft content even without publishedAt
`How it works:
- When a slug contains a GUID pattern (e.g.,
home-{userUid}), the SDK automatically:
1. Detects the GUID suffix
2. Extracts the base slug and userUid
3. Enables draft content access for this request
4. Returns user's draft version or falls back to base contentBenefits:
- โ
Zero configuration - works automatically with LeadCMS preview URLs
- ๐ Secure - only preview slugs (with valid GUID) can access drafts
- ๐ Backward compatible - normal slugs continue to require
publishedAt
- ๐ Developer-friendly - no additional parameters needed๐ See Draft Handling Guide for more details on preview mode and draft content handling.
$3
Media files are automatically synced during content pull:
`bash
Sync all media files
npx leadcms pullSync only media
npx leadcms pull-media
`๐ See Media Management Guide for media handling, optimization, and deployment strategies.
$3
Work with comments on your content:
`bash
Sync comments
npx leadcms pullSync only comments
npx leadcms pull-comments
``typescript
import {
getCommentsForContent,
getCommentsTreeForContent
} from '@leadcms/sdk';// Get flat list of comments
const comments = getCommentsForContent(contentId);
// Get comments as tree for threading
const tree = getCommentsTreeForContent(contentId, undefined, {
sortOrder: 'newest',
replySortOrder: 'oldest'
});
`๐ See Comment Tree Guide for complete documentation on threaded comments, sorting, filtering, and advanced features.
Docker Deployment
LeadCMS SDK includes framework-agnostic Docker templates for easy deployment:
$3
`bash
npx leadcms docker
`This creates:
-
Dockerfile - Production static site deployment
- nginx.conf - Optimized nginx configuration
- scripts/inject-runtime-env.sh - Runtime environment injection
- preview/Dockerfile - Development/preview environment
- preview/nginx.conf - Development proxy configuration
- preview/supervisord.conf - Multi-service management$3
`bash
1. Build your static site (framework-specific)
npm run build # Next.js: creates 'out' directory
npm run build # Astro: creates 'dist' directory
npm run build # Gatsby: creates 'public' directory
2. Build Docker image
docker build -t my-leadcms-site .3. Run container
docker run -p 80:80 \
-e LEADCMS_URL=https://your-instance.com \
-e LEADCMS_DEFAULT_LANGUAGE=en \
my-leadcms-site
`$3
`bash
1. Add livepreview script to package.json
{
"scripts": {
"livepreview": "next dev", // Next.js
// "livepreview": "astro dev", // Astro
// "livepreview": "gatsby develop", // Gatsby
// "livepreview": "nuxt dev" // Nuxt
}
}2. Build preview image
docker build -f preview/Dockerfile -t my-leadcms-site-preview .3. Run with live updates
docker run -p 80:80 \
-e LEADCMS_URL=https://your-instance.com \
-e LEADCMS_API_KEY=your-api-key \
-e LEADCMS_DEFAULT_LANGUAGE=en \
my-leadcms-site-preview
`Debugging
$3
Control SDK logging verbosity with environment variables:`bash
Enable debug logging (shows configuration loading messages)
LEADCMS_DEBUG=true npm run buildProduction mode (minimal logging)
NODE_ENV=production npm run build
`Debug mode is automatically enabled when
NODE_ENV=development or LEADCMS_DEBUG=true.$3
The SDK provides detailed error information for missing configuration files:`typescript
import { loadContentConfig, loadContentConfigStrict } from '@leadcms/sdk';// Graceful handling - returns null for missing files
const config = loadContentConfig('layout'); // Returns null if missing
// Strict handling - throws detailed errors for debugging
try {
const config = loadContentConfigStrict('layout');
} catch (error) {
console.log('Missing configuration:', error.configName);
console.log('Expected locale:', error.locale);
console.log('Full error:', error.message);
// Error message includes: configName, locale, and expected file path
}
`Error Details Include:
-
configName - The specific configuration name that was requested
- locale - The locale that was being loaded
- message - Full descriptive error including expected file path
- Clear console logging of missing files with exact paths$3
- โ
Use configuration files instead of programmatic configuration for better caching
- โ
The SDK caches file reads automatically - no manual optimization needed
- โ
In production builds, logging is minimal to reduce noise
- โ
Configuration is cached across multiple function calls within the same process
- โ
Use loadContentConfig() for optional configs, loadContentConfigStrict() for required configsFeatures & Documentation
$3
- Documentation Index - Central hub for all documentation
#### Content & Media
- Content Management - Retrieving, organizing, and working with content
- Media Management - Handling media files and optimization
- Draft Handling - Working with draft content and user-specific drafts
#### Comments
- Comment Tree Guide - Building threaded comment interfaces with sorting and filtering
#### Setup & Configuration
- Interactive Init - Setup wizard and authentication
- Public API Mode - Security-first approach and operation modes
#### Development
- Development Guide - Local development, testing, and debugging
- GitHub Actions - CI/CD setup and automated publishing
Development
For SDK development and contributions, see Development Guide.
Quick Start:
`bash
Clone and setup
git clone https://github.com/LeadCMS/leadcms.sdk.git
cd leadcms.sdk
npm install
npm run buildRun tests
npm testDevelopment mode
npm run dev
`Contributing:
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Run tests:
npm test`