SSG API

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:

JAVASCRIPT
headers: {
    'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
    'Content-Type': 'application/json'
}
JAVASCRIPT
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):

JSON
{
    "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 settings siteUrl)
  • cleanUrls - Use clean URLs without .html extension (default: true)

Success Response (200):

JSON
{
    "success": true,
    "message": "Static site generation started",
    "options": {
        "outputDir": "_site",
        "baseUrl": "https://mysite.com",
        "cleanUrls": true
    }
}

Error Responses:

JSON
// 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):

JSON
{
    "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.htmltemplates/index.htmltemplates/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.htmltemplates/content.htmltemplates/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}.htmlcustom/{taxonomy}.htmltemplates/taxonomy.htmltemplates/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:

  1. Homepage: custom/homepage.htmltemplates/home.htmltemplates/layout.html
  2. Custom Pages: custom/{slug}.htmlcustom/{parent-slug}.htmltemplates/layout.html
  3. Taxonomies: custom/{taxonomy-slug}.htmlcustom/{taxonomy}.htmltemplates/taxonomy.htmltemplates/layout.html
  4. Posts/Pages: templates/{type}.htmltemplates/content.htmltemplates/layout.html
🚨
Important: If no specific template is found, the system will fall back to the required templates/layout.html template.

Configuration

Site Settings Integration

The SSG uses these site settings as defaults:

JSON
{
    "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:

JSON
{
    "outputDir": "dist",
    "baseUrl": "https://cdn.mysite.com",
    "cleanUrls": false
}

Usage Examples

Basic Generation (Bearer Token)

JAVASCRIPT
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)
    }
}
JAVASCRIPT
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

JAVASCRIPT
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

JAVASCRIPT
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)

BASH
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)

JAVASCRIPT
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):

JSON
{
    "success": false,
    "error": "Unauthorized"
}

Permission Denied (403):

JSON
{
    "success": false,
    "error": "Only administrators can generate static sites"
}

Generation Failed (500):

JSON
{
    "success": false,
    "error": "Failed to generate static site",
    "message": "Template rendering failed"
}

Error Recovery

JAVASCRIPT
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

  1. Verify Authentication: Ensure you have a valid admin token
  2. Test Content: Ensure all posts and pages are properly formatted
  3. Check Links: Verify internal links are working
  4. Optimize Images: Compress images for faster loading
  5. Review Settings: Confirm base URL and output directory

After Generation

  1. Test Output: Check generated files load correctly
  2. Validate Links: Ensure all internal links work in static version
  3. Check SEO Files: Verify sitemap.xml and robots.txt are correct
  4. Performance Test: Test loading speed of generated pages

Deployment

  1. Use Clean URLs: Enable for better SEO and user experience
  2. Set Proper Base URL: Use your production domain
  3. Serve with HTTPS: Always use HTTPS for production sites
  4. 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.