SSG API
- Overview
- Authentication
- Bearer Token (Recommended)
- Cookie-based (Admin Panel)
- Important Notes
- API Endpoints
- Generate Static Site
- Get Generation Status
- Generated Site Structure
- Clean URLs (Default)
- Traditional URLs
- Generated Content Types
- Homepage
- Posts
- Pages
- Categories & Tags
- Custom Pages
- SEO Files
- Template Resolution
- Configuration
- Site Settings Integration
- Override in API Request
- Usage Examples
- Basic Generation (Bearer Token)
- Admin Panel Usage (Cookie Auth)
- Custom Configuration
- Check Status
- Performance Considerations
- Generation Speed (Real-World Performance)
- CLI vs API Performance
- CLI Command (Fastest)
- API Endpoint (Convenient)
- Memory Usage
- Optimization Features
- Error Handling
- Common Errors
- Error Recovery
- Best Practices
- Before Generation
- After Generation
- Deployment
- Security Considerations
Overview
The Static Site Generation (SSG) API allows administrators to generate static HTML versions of your Aether CMS site. This creates fast, secure, pre-rendered pages suitable for CDN deployment and improved performance.
Authentication
All SSG API endpoints require authentication. Use one of the following methods:
Bearer Token (Recommended)
headers: {
'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
'Content-Type': 'application/json'
}
Cookie-based (Admin Panel)
credentials: "include" // Uses authToken cookie from admin login
Important Notes
- Admin Only: Only users with admin role can trigger static generation
- Background Process: Generation runs server-side and continues even if browser is closed
- File Overwrite: New generation will overwrite the previous output directory
- Processing Time: Large sites may take several minutes to generate
API Endpoints
Generate Static Site
POST /api/static/generate
Requires Admin role
Starts static site generation in the background and returns immediately.
Request Body (Optional):
{
"outputDir": "_site",
"baseUrl": "https://mysite.com",
"cleanUrls": true
}
Parameters:
outputDir
- Output directory for generated files (default: from site settings or_site
)baseUrl
- Base URL for the site (default: from site settingssiteUrl
)cleanUrls
- Use clean URLs without .html extension (default:true
)
Success Response (200):
{
"success": true,
"message": "Static site generation started",
"options": {
"outputDir": "_site",
"baseUrl": "https://mysite.com",
"cleanUrls": true
}
}
Error Responses:
// 403 Forbidden
{
"success": false,
"error": "Only administrators can generate static sites"
}
// 401 Unauthorized
{
"success": false,
"error": "Unauthorized"
}
Get Generation Status
GET /api/static/status
Requires Admin role
Returns configuration information and settings.
Success Response (200):
{
"success": true,
"status": "ready",
"lastGenerated": "2024-01-01T12:00:00.000Z",
"settings": {
"staticOutputDir": "_site",
"siteUrl": "https://mysite.com",
"staticCleanUrls": true
}
}
Note: Currently returns configuration information rather than real-time generation progress.
Generated Site Structure
Clean URLs (Default)
When cleanUrls: true
, the generated structure uses directory-based URLs:
_site/
├── index.html # Homepage
├── page/2/index.html # Homepage page 2 (if paginated)
├── post/
│ ├── my-first-post/index.html # Individual posts
│ └── another-post/index.html
├── page/
│ ├── about/index.html # Static pages
│ └── contact/index.html
├── category/
│ ├── technology/index.html # Category page 1
│ └── technology/page/2/index.html # Category page 2
├── tag/
│ ├── javascript/index.html # Tag pages
│ └── css/index.html
├── documentation/index.html # Custom pages
├── documentation/
│ ├── getting-started/index.html # Nested custom pages
│ └── api-guide/index.html
├── content/
│ ├── themes/active-theme/assets/ # Theme assets
│ └── uploads/ # Media files
├── sitemap.xml # XML sitemap
├── sitemap/index.html # HTML sitemap
├── rss.xml # RSS feed
└── robots.txt # Robots.txt
Traditional URLs
When cleanUrls: false
:
_site/
├── index.html
├── page-2.html
├── post/my-first-post.html
├── post/another-post.html
├── page/about.html
├── category/technology.html
├── category/technology/page-2.html
└── ...
Generated Content Types
Homepage
- Template:
custom/homepage.html
→templates/index.html
→templates/layout.html
- Content: Latest posts with pagination
- Data: Published posts, site settings, navigation menu
Posts
- Path:
/post/{slug}/
(clean URLs) or/post/{slug}.html
- Template:
templates/post.html
→templates/content.html
→templates/layout.html
- Content: Full post content with metadata
- Data: Post content, related posts, prev/next navigation
Pages
- Path:
/page/{slug}/
or/{slug}/
(custom pages) - Template:
templates/page.html
→ custom templates for custom pages →templates/layout.html
- Content: Page content with metadata
Categories & Tags
- Path:
/category/{slug}/
or/tag/{slug}/
- Template:
custom/{taxonomy-slug}.html
→custom/{taxonomy}.html
→templates/taxonomy.html
→templates/layout.html
- Content: Posts in category/tag with pagination
Custom Pages
Custom pages support advanced features:
- Blog-style Pages: Pages like
/blog/
automatically include post pagination - Taxonomy Pages: Pages like
/categories/
show all categories with post counts - Hierarchical Pages: Nested pages like
/docs/getting-started/
with breadcrumb navigation
SEO Files
- XML Sitemap (
sitemap.xml
): All content with proper metadata - HTML Sitemap (
sitemap/index.html
): User-friendly sitemap page - RSS Feed (
rss.xml
): All published posts with full content - Robots.txt: Search engine directives with sitemap references
Template Resolution
The SSG, like the CMS, uses intelligent template resolution with fallbacks:
- Homepage:
custom/homepage.html
→templates/home.html
→templates/layout.html
- Custom Pages:
custom/{slug}.html
→custom/{parent-slug}.html
→templates/layout.html
- Taxonomies:
custom/{taxonomy-slug}.html
→custom/{taxonomy}.html
→templates/taxonomy.html
→templates/layout.html
- Posts/Pages:
templates/{type}.html
→templates/content.html
→templates/layout.html
templates/layout.html
template.
Configuration
Site Settings Integration
The SSG uses these site settings as defaults:
{
"siteTitle": "My Aether Site",
"siteDescription": "A site built with Aether",
"postsPerPage": 10,
"activeTheme": "default",
"footerCode": "Content in Motion. Powered by Aether.",
"siteUrl": "/",
"staticOutputDir": "_site",
"staticCleanUrls": true
}
Override in API Request
You can override settings when making the API request:
{
"outputDir": "dist",
"baseUrl": "https://cdn.mysite.com",
"cleanUrls": false
}
Usage Examples
Basic Generation (Bearer Token)
async function generateStaticSite() {
try {
const response = await fetch("/api/static/generate", {
method: "POST",
headers: {
Authorization: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"Content-Type": "application/json",
},
})
const result = await response.json()
if (result.success) {
console.log("✅ Static site generation started")
console.log("Output:", result.options.outputDir)
console.log("Base URL:", result.options.baseUrl)
} else {
console.error("❌ Generation failed:", result.error)
}
} catch (error) {
console.error("❌ Request failed:", error)
}
}
Admin Panel Usage (Cookie Auth)
async function generateFromAdminPanel() {
try {
const response = await fetch("/api/static/generate", {
method: "POST",
credentials: "include", // Uses authToken cookie
headers: {
"Content-Type": "application/json",
},
})
const result = await response.json()
if (result.success) {
console.log("✅ Generation started from admin panel")
return result.options
} else {
throw new Error(result.error)
}
} catch (error) {
console.error("❌ Generation failed:", error)
throw error
}
}
Custom Configuration
async function generateWithCustomConfig() {
const config = {
outputDir: "public",
baseUrl: "https://cdn.example.com",
cleanUrls: true,
}
try {
const response = await fetch("/api/static/generate", {
method: "POST",
headers: {
Authorization: "Bearer your-token-here",
"Content-Type": "application/json",
},
body: JSON.stringify(config),
})
const result = await response.json()
if (result.success) {
console.log("✅ Custom generation started")
return result.options
} else {
throw new Error(result.error)
}
} catch (error) {
console.error("❌ Custom generation failed:", error)
throw error
}
}
Check Status
async function checkGenerationStatus() {
try {
const response = await fetch("/api/static/status", {
headers: {
Authorization: "Bearer your-token-here",
},
})
const result = await response.json()
if (result.success) {
console.log("Status:", result.status)
console.log("Settings:", result.settings)
return result
}
} catch (error) {
console.error("❌ Status check failed:", error)
}
}
Performance Considerations
Generation Speed (Real-World Performance)
- Small Sites (< 25 pages): 0.2-0.5 seconds
- Medium Sites (25-100 pages): 0.5-2 seconds
- Large Sites (100-300 pages): 2-8 seconds
- Very Large Sites (300+ pages): 8-20 seconds
Tested with complex hierarchical custom pages including long content, images, navigation, and full SEO generation.
CLI vs API Performance
CLI Command (Fastest)
npm run build
- Direct execution without HTTP overhead
- No authentication processing
- Fastest method - approximately 300ms faster than API
- Recommended for automated builds and CI/CD
API Endpoint (Convenient)
POST / api / static / generate
- HTTP request overhead adds ~300ms
- Authentication and JSON parsing processing time
- Background execution after immediate response
- Ideal for admin panel integration
Memory Usage
- Batch Processing: Pages processed in groups to manage memory
- Efficient File I/O: Optimized file operations and streaming
- Resource Cleanup: Automatic cleanup of temporary objects
- Direct Template Resolution: Fast template path resolution without overhead
Optimization Features
- Clean URLs: SEO-friendly structure
- Asset Copying: Only active theme assets copied
- Metadata Exclusion:
.metadata.json
files excluded from output
Error Handling
Common Errors
Authentication Required (401):
{
"success": false,
"error": "Unauthorized"
}
Permission Denied (403):
{
"success": false,
"error": "Only administrators can generate static sites"
}
Generation Failed (500):
{
"success": false,
"error": "Failed to generate static site",
"message": "Template rendering failed"
}
Error Recovery
async function generateWithRetry(options, maxRetries = 2) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await generateStaticSite(options)
} catch (error) {
console.warn(`Attempt ${attempt} failed:`, error.message)
if (attempt === maxRetries) {
throw new Error(`Generation failed after ${maxRetries} attempts`)
}
// Wait before retry
await new Promise((resolve) => setTimeout(resolve, 5000))
}
}
}
Best Practices
Before Generation
- Verify Authentication: Ensure you have a valid admin token
- Test Content: Ensure all posts and pages are properly formatted
- Check Links: Verify internal links are working
- Optimize Images: Compress images for faster loading
- Review Settings: Confirm base URL and output directory
After Generation
- Test Output: Check generated files load correctly
- Validate Links: Ensure all internal links work in static version
- Check SEO Files: Verify sitemap.xml and robots.txt are correct
- Performance Test: Test loading speed of generated pages
Deployment
- Use Clean URLs: Enable for better SEO and user experience
- Set Proper Base URL: Use your production domain
- Serve with HTTPS: Always use HTTPS for production sites
- Configure Caching: Set appropriate cache headers on your server
Security Considerations
- Admin Only Access: Generation requires admin role for security
- Token Security: Keep authentication tokens secure and rotate regularly
- Output Directory: Ensure output directory has proper write permissions
- Base URL Validation: Validate base URL to prevent injection attacks
The Static Site Generation API provides a secure, efficient way to create fast, static versions of your Aether CMS content suitable for modern web deployment.