@leadcms/sdk
v3.1.1
Published
Official SDK and CLI tools for LeadCMS - framework-agnostic content management for static site generators
Maintainers
Readme
LeadCMS SDK
A 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.
Installation
For Build-Time Usage (Most Common)
If you only use LeadCMS SDK during the build process (static site generation):
npm install --save-dev @leadcms/sdkFor Runtime Usage
If you need LeadCMS SDK in your production application (SSR, API routes, live preview):
npm install @leadcms/sdkGlobal CLI Installation
For CLI tools and project setup:
npm install -g @leadcms/sdkWhen to Use Each Installation Method
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
Quick Start
Get started with LeadCMS in 3 simple steps:
1. Initialize Your Project
npx leadcms initThis will:
- Connect to your LeadCMS instance
- Detect available entity types (content, media, comments)
- Create configuration files (
.envand optionallyleadcms.config.json)
2. Authenticate (for write access)
npx leadcms login- LeadCMS v1.2.88+: Automatic device authentication via browser
- Older versions: Guided manual token extraction
- Saves your API token securely to
.env
Skip this step if you only need read-only access to public content.
3. Download Your Content
npx leadcms pullDownloads 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:
🧪 Automated Testing
- 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
📊 Coverage Reporting
- 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
🔧 Quality Checks
- 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
Setting Up CI/CD for Your Project
If you're using this SDK in your own project, you can add similar testing workflows:
# .github/workflows/test.yml
name: Tests
on: [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 testRunning Tests Locally
# Run all tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watchTest Coverage
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
Testing with Mock Data
For testing CLI commands locally without a real LeadCMS instance, use the built-in mock data service:
# Enable mock mode and test status command
LEADCMS_USE_MOCK=true LEADCMS_CONTENT_DIR=./test-content npx leadcms status
# Test 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-runAvailable Mock Scenarios:
allNew- Local content that doesn't exist remotely (default)noChanges- All content is in synchasConflicts- Remote content is newer than localhasUpdates- Local content is newer than remotemixedOperations- Mix of new, updated, and conflicted contentmissingContentTypes- Content with unknown types
Mock Mode Activation:
NODE_ENV=test- Automatically uses mock modeLEADCMS_USE_MOCK=true- Force mock mode
The 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 initfor an interactive setup wizard that handles everything!
1. Environment Variables (Recommended for API credentials)
For security reasons, it's best to keep sensitive credentials as environment variables:
# Required
LEADCMS_URL=your-leadcms-instance-url
# Optional - API key for authenticated access
# Omit this for public-only mode (published content only)
LEADCMS_API_KEY=your-api-key
# Optional - can also be set via environment variables
LEADCMS_DEFAULT_LANGUAGE=en
LEADCMS_CONTENT_DIR=.leadcms/content
LEADCMS_MEDIA_DIR=public/media
LEADCMS_ENABLE_DRAFTS=true
# Next.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.
2. Configuration File (For project-specific settings)
Create a leadcms.config.json file only if you need to override default settings like contentDir, mediaDir, or defaultLanguage:
# Initialize configuration file
npx leadcms init{
"defaultLanguage": "en",
"contentDir": ".leadcms/content",
"mediaDir": "public/media",
"enableDrafts": false
}Security Note: Avoid putting
urlandapiKeyin config files. Environment variables are safer and work better with deployment platforms.
3. Programmatic Configuration
For advanced use cases, you can configure the SDK programmatically:
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
urlandapiKey, and programmatic configuration only for project-specific overrides.
Configuration Options
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
Check SDK version
npx leadcms version
# or
npx leadcms -v
# or
npx leadcms --versionInitialize configuration
npx leadcms initInteractive setup wizard that:
- Connects to your LeadCMS instance - Validates URL and checks for existing authentication
- Fetches configuration - Retrieves default language and available languages from public
/api/configendpoint - Configures directories - Sets content and media directories (defaults:
.leadcms/content,public/media) - Creates environment file - Saves configuration to
.env - 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.
Login to LeadCMS
npx leadcms loginAuthenticates 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
.envfile
When to use:
- After running
leadcms initif you need write access - To update an expired or invalid token
- When switching between LeadCMS instances
Example session:
🚀 LeadCMS SDK Initialization
Enter 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 projectThe wizard creates:
.env(or.envif exists) withLEADCMS_URL,LEADCMS_DEFAULT_LANGUAGE, and optionallyLEADCMS_API_KEYleadcms.config.jsononly if custom directories are specified
Anonymous Mode: Perfect for static sites that only need public content. Omit the API key to skip authentication entirely.
Generate Docker deployment templates
npx leadcms docker
# Creates Docker files for production and preview deploymentsPull content, media and comments from LeadCMS
The CLI supports several focused pull commands so you can sync exactly what you need.
# Pull everything (content, media, comments)
npx leadcms pull
# Pull only content (no media or comments)
npx leadcms pull-content
# Pull only media files
npx leadcms pull-media
# Pull only comments
npx leadcms pull-commentsNote:
npx leadcms fetchis 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 yourmediaDir(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.
Push local content to LeadCMS
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
updatedAttimestamps - Prompt for confirmation before making changes
- Support for creating missing content types automatically
- Update local files with remote metadata (id, createdAt, updatedAt) after sync
Options:
--force- Override remote changes (skip conflict check)
Content frontmatter / metadata (required and optional fields):
---
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:
publishedAtis optional. Omitting it is a valid way to create draft or scheduled content depending on your LeadCMS workflow.updatedAtis typically set and maintained by the LeadCMS server after content is created or updated. The SDK will useupdatedAtwhen present for conflict detection, but you should not rely on it being set for brand-new local files.
Check sync status
npx leadcms statusShows 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.
Watch for real-time updates
npx leadcms watchFramework Integration
The SDK provides framework-agnostic data access. Most frameworks use it as a development dependency for build-time static generation:
// 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
Content API
Get content from your LeadCMS instance:
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:
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 publishedAtHow it works:
- When a slug contains a GUID pattern (e.g.,
home-{userUid}), the SDK automatically:- Detects the GUID suffix
- Extracts the base slug and userUid
- Enables draft content access for this request
- Returns user's draft version or falls back to base content
Benefits:
- ✅ 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.
Media API
Media files are automatically synced during content pull:
# Sync all media files
npx leadcms pull
# Sync only media
npx leadcms pull-media📖 See Media Management Guide for media handling, optimization, and deployment strategies.
Comments API
Work with comments on your content:
# Sync comments
npx leadcms pull
# Sync only comments
npx leadcms pull-commentsimport {
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:
Generate Templates
npx leadcms dockerThis creates:
Dockerfile- Production static site deploymentnginx.conf- Optimized nginx configurationscripts/inject-runtime-env.sh- Runtime environment injectionpreview/Dockerfile- Development/preview environmentpreview/nginx.conf- Development proxy configurationpreview/supervisord.conf- Multi-service management
Production Deployment
# 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-sitePreview/Development Mode
# 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-previewDebugging
Debug Logging
Control SDK logging verbosity with environment variables:
# Enable debug logging (shows configuration loading messages)
LEADCMS_DEBUG=true npm run build
# Production mode (minimal logging)
NODE_ENV=production npm run buildDebug mode is automatically enabled when NODE_ENV=development or LEADCMS_DEBUG=true.
Error Handling
The SDK provides detailed error information for missing configuration files:
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 requestedlocale- The locale that was being loadedmessage- Full descriptive error including expected file path- Clear console logging of missing files with exact paths
Performance Tips
- ✅ 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 configs
Features & Documentation
📚 Complete Guides
- 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:
# Clone and setup
git clone https://github.com/LeadCMS/leadcms.sdk.git
cd leadcms.sdk
npm install
npm run build
# Run tests
npm test
# Development mode
npm run devContributing:
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
npm test - Submit a pull request
