System Integration
System Integration: Built-in Sources (Examples 11β13)
SSI provides built-in data sources that integrate with your system environment, git repository, and datetime. This section covers examples 11β13: system data, non-HTML processing, and incremental builds.
Example 13: Built-in Data Sources
SSI provides three built-in data source types that donβt require any files.
DateTime Source
Add build timestamps and dates to your site:
[[step]]
emoji = "π"
processing = "include"
type = "datetime"
timezone = "UTC" # Optional: use specific IANA timezone
options = ["inline"]
Available tokens:
<!-- Date components -->
<p>Built: πmonth_name πday, πyear</p>
<!-- Time components -->
<p>Time: πhour:πminute πam_pm πtz</p>
<!-- ISO format -->
<p>Timestamp: πiso</p>
Common tokens:
- Date:
year,month,day,month_name,month_short,day_of_week,day_short - Time:
hour,hour12,minute,second,am_pm - Timezone:
tz,timezone,utc_offset,utc_offset_hours - Formatted:
iso,date,time,rfc3339,build_timestamp
Timezone control:
The optional timezone field specifies an IANA timezone:
[[step]]
emoji = "π"
type = "datetime"
timezone = "America/New_York"
options = ["inline"]
If omitted, uses the TZ environment variable:
# Use specific timezone via environment
TZ=America/New_York ssi deploy site/ output/
Git Source
Embed git information in your build:
[[step]]
emoji = "π§"
processing = "include"
type = "git"
path = ".git/"
options = ["inline"]
Available tokens:
<footer>
<p>Version: abc123</p>
<p>Branch: main</p>
<p>Repository: https://github.com/example/repo</p>
</footer>
Available git data:
branchβ Current branch namecommitβ Full commit hashcommit-shortβ First 10 characters of commit hashremote-originβ Origin remote URLremote-[name]β Any git remotedescriptionβ Repository description
Security notes:
- Reads
.git/files directly (no git command needed) - Works in CI/CD without git installed
- Safe for production (no command execution)
Environment Variables
Expose selected environment variables via an allowlist:
[[step]]
emoji = "π"
processing = "include"
type = "environment"
path = "allowed-env.txt"
options = ["inline"]
Allowlist file (allowed-env.txt):
# Build information
BUILD_NUMBER
BUILD_ID
CI_COMMIT_SHA
# Application info
APP_VERSION
APP_NAME
In templates:
<p>Build: πBUILD_NUMBER</p>
<p>Version: πAPP_VERSION</p>
<p>Commit: πCI_COMMIT_SHA</p>
Security:
- Allowlist approach β only listed variables are accessible
- No wildcards or patterns
- Missing variables return empty strings
- Never expose secrets or credentials
Try it:
cd examples/14-builtin-sources
ssi deploy site/ output/
Example 14: Non-HTML Template Processing
SSI can process CSS and JavaScript files as templates using no-escape:
[[step]]
emoji = "π¨"
path = "css/"
processing = "page"
[[step]]
emoji = "π¨"
path = "css-vars/"
processing = "include"
type = "plain"
options = ["no-escape", "inline"]
CSS with Design Tokens
Configuration file (css-vars/theme.txt):
--primary: #3b82f6
--secondary: #8b5cf6
--font-sans: 'Inter', system-ui, sans-serif
--shadow: 0 4px 6px rgba(0,0,0,0.1)
CSS template (css/theme.css):
:root {
--primary-color: π¨--primary;
--secondary-color: π¨--secondary;
--font-family: π¨--font-sans;
--box-shadow: π¨--shadow;
}
JavaScript Configuration
[[step]]
emoji = "βοΈ"
path = "js-config/"
processing = "include"
type = "plain"
options = ["no-escape", "inline"]
Config file (js-config/api.txt):
https://api.example.com/v2
JS template (js/app.js):
const CONFIG = {
apiEndpoint: 'https://api.example.com',
version: '2.1.0',
};
fetch('https://api.example.com/users')
.then(response => response.json());
Why use no-escape:
- Default behavior HTML-escapes special characters
no-escapekeeps content as-is for CSS and JS- Only use for developer-controlled content β never for user-generated content
Try it:
cd examples/16-css-js-templates
ssi deploy site/ output/
cat output/theme.css # See the replaced variables
Example 14: Incremental Builds with Preserve
Preserve dynamically-generated files across deployments:
[[step]]
emoji = "π"
path = "pages/"
processing = "page"
[[step]]
emoji = "π"
path = "preservelist.txt"
processing = "preserve"
Preserve list (preservelist.txt):
# Dynamic content to preserve
sitemap.xml
robots.txt
# Generated assets
search-index.json
# Log files
logs/access.log
How it works:
- SSI reads the previous deployment directory
- Copies listed files to the new deployment
- Leaves other files alone
- Works well with atomic deployments
Use cases:
- Search indexes generated by other tools
- Sitemaps updated separately
- User-uploaded content
- Cache files
Security:
- Paths must be relative
- No
../path traversal - No absolute paths
- Violations cause build failure
Try it:
cd examples/17-file-handling
# First deployment
ssi deploy site/ output/
# Create a file to preserve
echo "test" > output/dynamic-file.txt
# Add to preservelist.txt
echo "dynamic-file.txt" >> site/preservelist.txt
# Second deployment β file preserved
ssi deploy site/ output/
cat output/dynamic-file.txt # Still there!
Combining System Integration
A production configuration using all system features:
# Page processing
[[step]]
emoji = "π"
path = "pages/"
processing = "page"
# Static assets
[[step]]
emoji = "π¨"
path = "assets/"
processing = "copy"
options = ["checksum"]
# Build information
[[step]]
emoji = "π"
processing = "include"
type = "datetime"
options = ["inline"]
# Git information
[[step]]
emoji = "π§"
processing = "include"
type = "git"
path = ".git/"
options = ["inline"]
# CI environment
[[step]]
emoji = "π"
processing = "include"
type = "environment"
path = "allowed-env.txt"
options = ["inline"]
# Preserve dynamic content
[[step]]
emoji = "π"
path = "preservelist.txt"
processing = "preserve"
Template usage:
<footer>
<p>Built: πiso</p>
<p>Version: abc123 on main</p>
<p>Build #πBUILD_NUMBER</p>
</footer>
Best Practices
DateTime:
- Always use
inlineoption for datetime - Set
TZenvironment variable for consistent timezones - Use
isoorrfc3339for machine-readable timestamps
Git:
- Path must end with
.git/ - Returns empty strings if git data is missing
- Use
commit-shortfor display
Environment:
- Never expose secrets or credentials
- Use the allowlist approach
- Keep the allowlist file in version control
Preserve:
- Only use for files generated outside SSI
- Keep the preserve list in version control
- Document why each file is preserved