Super-Simple Includes Documentation

v0.244.0

Building Production Sites

Production Patterns

These patterns cover best practices for production deployments, building on the techniques from the examples.

Full-Site Architecture

Example 99 demonstrates a complete production site using all SSI features together.

# 1. Page processing
                [[step]]
                emoji = "πŸ“„"
                path = "pages/"
                processing = "page"
                
                # 2. Reusable HTML components
                [[step]]
                emoji = "πŸ“Ž"
                path = "blocks/"
                processing = "include"
                type = "html"
                
                # 3. Content (per-page resolution)
                [[step]]
                emoji = "πŸ“"
                path = "content/"
                processing = "include"
                type = "html"
                
                # 4. Site-wide variables
                [[step]]
                emoji = "πŸ’¬"
                path = "texts/"
                processing = "include"
                type = "plain"
                options = ["inline"]
                

This architecture separates:

  • Structure (pages/) β€” HTML skeleton
  • Components (blocks/) β€” Reusable UI widgets
  • Content (content/) β€” Page-specific content
  • Variables (texts/) β€” Site-wide strings

Directory structure:

site/
                β”œβ”€β”€ ssi-config.toml
                β”œβ”€β”€ pages/
                β”‚   β”œβ”€β”€ index.html
                β”‚   β”œβ”€β”€ about.html
                β”‚   └── details.html
                β”œβ”€β”€ blocks/
                β”‚   β”œβ”€β”€ header.html
                β”‚   β”œβ”€β”€ footer.html
                β”‚   └── nav.html
                β”œβ”€β”€ content/
                β”‚   β”œβ”€β”€ index/          # Per-page content
                β”‚   β”‚   β”œβ”€β”€ hero.html
                β”‚   β”‚   └── features.html
                β”‚   β”œβ”€β”€ about/
                β”‚   β”‚   └── story.html
                β”‚   └── details/
                β”‚       └── info.html
                └── texts/
                    β”œβ”€β”€ site-name.txt
                    β”œβ”€β”€ license-notice.txt
                    └── tagline.txt
                

Try it:

cd examples/99-full-site
                ssi deploy site/ output/
                

Production Configuration Patterns

Validated Assets

Use checksums for critical files:

[[step]]
                emoji = "πŸ“¦"
                path = "assets/"
                processing = "copy"
                options = ["checksum"]
                
                [[step]]
                emoji = "πŸ”€"
                path = "fonts/"
                destination = "fonts"
                processing = "copy"
                

Generate checksums:

xxh3sum assets/* > assets.xxh3
                xxh3sum fonts/* > fonts.xxh3
                

Build Information Footer

Embed build metadata in every page:

[[step]]
                emoji = "πŸ•’"
                processing = "include"
                type = "datetime"
                options = ["inline"]
                
                [[step]]
                emoji = "πŸ”§"
                processing = "include"
                type = "git"
                path = ".git/"
                options = ["inline"]
                
                [[step]]
                emoji = "🌍"
                processing = "include"
                type = "environment"
                path = "allowed-env.txt"
                options = ["inline"]
                

Footer component (blocks/build-info.html):

<footer class="build-info">
                    <p>Built: πŸ•’iso</p>
                    <p>Version: abc123 (main)</p>
                    <p>Build: #🌍BUILD_NUMBER</p>
                </footer>
                

Component Library

SSI’s flat processing means subdirectories are ignored. Use prefixed filenames to organize your components:

blocks/
                β”œβ”€β”€ layout-header.html
                β”œβ”€β”€ layout-footer.html
                β”œβ”€β”€ ui-alert-info.html
                β”œβ”€β”€ ui-card.html
                └── nav-breadcrumb.html
                

Multi-Environment Configuration

Use environment variables for deployment targets:

allowed-env.txt:

DEPLOY_ENV
                API_ENDPOINT
                CDN_URL
                

In templates:

<script>
                    const CONFIG = {
                        environment: '🌍DEPLOY_ENV',
                        api: '🌍API_ENDPOINT',
                        cdn: '🌍CDN_URL'
                    };
                </script>
                

Deploy:

# Production
                DEPLOY_ENV=production \
                API_ENDPOINT=https://api.example.com \
                CDN_URL=https://cdn.example.com \
                ssi deploy site/ production/
                
                # Staging
                DEPLOY_ENV=staging \
                API_ENDPOINT=https://staging-api.example.com \
                CDN_URL=https://staging-cdn.example.com \
                ssi deploy site/ staging/
                

Performance

Incremental Deployments

Preserve dynamically-generated content across rebuilds:

[[step]]
                emoji = "πŸ”’"
                path = "preservelist.txt"
                processing = "preserve"
                

preservelist.txt:

# Search index (generated by external tool)
                search-index.json
                
                # Sitemap (updated separately)
                sitemap.xml
                
                # User uploads
                uploads/*.jpg
                uploads/*.png
                

Security

HTML Escaping

Use appropriate content types:

# Safe: HTML-escaped by default
                [[step]]
                emoji = "πŸ“œ"
                path = "user-content/"
                processing = "include"
                type = "plain"
                
                # Only for developer-controlled content
                [[step]]
                emoji = "πŸ“Ž"
                path = "trusted-blocks/"
                processing = "include"
                type = "html"
                

Environment Variable Allowlist

Never expose secrets:

# Good: build metadata
                APP_VERSION
                BUILD_NUMBER
                DEPLOY_ENV
                
                # Bad: never expose secrets
                # DATABASE_PASSWORD
                # API_KEY
                # SECRET_TOKEN
                

Path Validation

Preserve lists are validated automatically:

# Good
                sitemap.xml
                images/hero.jpg
                
                # Bad (rejected automatically)
                # /etc/passwd          ← Absolute path
                # ../../../secret      ← Path traversal
                

External Paths

Only enable when necessary:

[[step]]
                emoji = "πŸ“š"
                path = "../shared-docs/"
                processing = "include"
                type = "markdown"
                options = ["allow-external-paths"]  # Explicit opt-in
                

Requires CLI flag:

ssi --allow-external-paths deploy site/ output/
                

CI/CD Integration

GitHub Actions

name: Deploy Site
                
                on:
                  push:
                    branches: [main]
                
                jobs:
                  deploy:
                    runs-on: ubuntu-latest
                    steps:
                      - uses: actions/checkout@v3
                
                      - name: Install SSI
                        run: |
                          cargo build --release --target x86_64-unknown-linux-musl
                          cp target/x86_64-unknown-linux-musl/release/ssi /usr/local/bin/
                
                      - name: Generate checksums
                        run: |
                          xxh3sum site/assets/* > site/assets.xxh3
                
                      - name: Deploy site
                        env:
                          BUILD_NUMBER: ${{ github.run_number }}
                          DEPLOY_ENV: production
                        run: |
                          ssi deploy site/ output/
                
                      - name: Upload to server
                        run: |
                          rsync -avz --delete output/ server:/var/www/html/
                

The same pattern adapts to GitLab CI, Codeberg Actions, and other CI systems β€” replace the Actions-specific syntax with the equivalent for your platform.

Deployment Checklist

Before production deployment:

  • All examples tested locally
  • Checksums generated for static assets
  • Environment variables configured
  • Preserve list reviewed (if using preserve)
  • Build info footer added
  • External paths minimized or eliminated
  • No secrets in environment allowlist
  • Link validation passed (ssi validate)
  • No unused files (ssi validate --warn-unused)
  • Tests pass in CI/CD

Common Patterns

Blog

[[step]]
                emoji = "πŸ“„"
                path = "pages/"
                processing = "page"
                
                [[step]]
                emoji = "πŸ“"
                path = "posts/"
                processing = "include"
                type = "markdown"
                options = ["markdown-h2"]  # Shift headers for page structure
                
                [[step]]
                emoji = "πŸ“Ž"
                path = "blocks/"
                processing = "include"
                type = "html"
                

Documentation Site

[[step]]
                emoji = "πŸ“„"
                path = "pages/"
                processing = "page"
                
                [[step]]
                emoji = "πŸ“"
                path = "docs/"
                processing = "include"
                type = "markdown"
                
                [[step]]
                emoji = "πŸ“Ž"
                path = "components/"
                processing = "include"
                type = "html"
                
                [[step]]
                emoji = "πŸ’¬"
                path = "strings.toml"
                processing = "include"
                type = "plain"
                options = ["inline"]
                

Landing Page

[[step]]
                emoji = "πŸ“„"
                path = "pages/"
                processing = "page"
                
                [[step]]
                emoji = "πŸ“Ž"
                path = "sections/"  # Hero, features, testimonials
                processing = "include"
                type = "html"
                
                [[step]]
                emoji = "πŸ’¬"
                path = "copy.toml"  # Marketing copy
                processing = "include"
                type = "plain"
                options = ["inline"]
                
                [[step]]
                emoji = "🎨"
                path = "assets/"
                processing = "copy"