Skip to content
spaguPublic

About

A simple static site generator written in Go. Converts content from WordPress exports (Markdown format with YAML frontmatter) to static HTML, CSS, and JS files.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

4 stars

Watchers

1 watching

Forks

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Latest commit

 

History

745 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

SSG — Static Site Generator

Go Version CI Go Report Card codecov GitHub Release License

SSG is a fast static site generator written in Go. It turns Markdown with YAML frontmatter into a complete website with clean URLs, templates, feeds, search, image processing and optional native deployment.

It works especially well for blogs and WordPress migrations, but can also build documentation, company sites, portfolios and landing pages.

Quick start · Content model · Configuration · Templates · Deployment · Documentation

Why SSG?

  • Fast, deterministic builds with a single Go binary
  • Markdown content with YAML frontmatter
  • Built-in simple, krowy and apidoc (documentation) themes
  • Go, Pongo2, Mustache and Handlebars template engines
  • Sitemap, robots.txt, Atom feeds, search index and SEO metadata
  • WebP conversion, responsive images, SCSS, minification and fingerprinting
  • Local server with automatic rebuilds
  • Redirects engine with chain flattening and a redirects()-config importer
  • Cloudflare Pages Functions integration for payments, forms and dynamic endpoints
  • Native deployment to Cloudflare Pages, GitHub Pages, Netlify, Vercel, FTP and SFTP
  • GitHub Action and multi-architecture Docker images

Most advanced features are opt-in. A basic command only reads content, renders HTML and writes the result to output/.

Quick start

1. Install SSG

Linux and macOS:

curl -sSL https://raw.githubusercontent.com/spagu/ssg/main/install.sh | bash
# verifies the download against the release's checksums.sha256 before installing

Other supported installation methods:

Method Command or location
Homebrew brew install spagu/tap/ssg
Snap snap install static-site-generator && sudo snap alias static-site-generator ssg
Release binaries and packages GitHub Releases
Docker Hub docker pull tradik/ssg:latest
GitHub Container Registry docker pull ghcr.io/spagu/ssg:latest
Build from source make build

For platform-specific instructions, see docs/INSTALL.md. Already running an older SSG? docs/UPGRADING.md lists every step between your version and this one — most upgrades need none.

2. Create the smallest useful site

The fastest way is ssg init, which scaffolds a ready-to-build project — config, a content source with a sample page and post, a static/ folder and a .gitignore — without overwriting anything that already exists:

ssg init my-blog --domain blog.example.com
ssg --config .ssg.yaml --http --watch

Or lay it out by hand:

content/
└── my-blog/
    ├── metadata.json
    ├── pages/
    │   └── about.md
    └── posts/
        └── general/
            └── hello.md

content/my-blog/metadata.json:

{
  "title": "My Blog",
  "description": "Thoughts and notes",
  "url": "https://example.com",
  "language": "en",
  "categories": [{ "id": 1, "name": "General", "slug": "general" }],
  "users": [{ "id": 1, "name": "Editor", "slug": "editor" }],
  "media": []
}

content/my-blog/pages/about.md:

---
title: About
slug: about
status: publish
type: page
---

This is my first page.

content/my-blog/posts/general/hello.md:

---
title: Hello World
slug: hello-world
status: publish
type: post
date: 2026-04-01
categories: [General]
author: 1
---

This is my first post.

3. Build and preview

ssg my-blog simple example.com --http --watch

Open http://127.0.0.1:8888. SSG rebuilds the site when its files change. The generated site is written to output/; do not edit that directory by hand.

The simple, krowy and apidoc themes are embedded in the binary and scaffolded when first used, so this example does not require a local templates/simple/ folder.

Command model

ssg <source> <template> <domain> [options]
Argument Meaning Default location or use
source Content collection name content/<source>/
template Theme name templates/<template>/ or an embedded theme
domain Canonical host without a scheme Canonical URLs, feeds, sitemap and SEO

Example:

ssg my-blog krowy example.com --clean --minify-all

This reads content/my-blog/, uses the krowy theme, treats https://example.com as the canonical site root and writes to output/.

All three values may instead be provided by a configuration file. In MDDB mode, content is fetched remotely and the source argument is optional.

Content model

SSG uses explicit locations and predictable output rules. These rules are useful both when authoring a site manually and when generating one programmatically.

Directory contract

project/
├── .ssg.yaml                  # optional configuration
├── content/
│   └── <source>/
│       ├── metadata.json      # required for a local content source
│       ├── pages/             # recursively loaded pages
│       ├── posts/
│       │   └── <group>/       # at least one directory below posts/
│       │       └── post.md    # deeper nesting is allowed
│       └── media/             # optional content media
├── templates/
│   └── <template>/            # optional when using an embedded theme
├── data/                      # optional YAML/JSON template data
├── static/                    # optional files copied verbatim
└── output/                    # generated; safe to delete and rebuild

Important invariants:

  1. Pages are loaded recursively from pages/.
  2. Posts must be inside at least one subdirectory of posts/. Files directly in posts/ are ignored. Below the first subdirectory, nesting is recursive.
  3. A post's category comes from its categories frontmatter, not its directory.
  4. Local builds require metadata.json at the root of the selected source.
  5. Files with frontmatter are rendered only when status: publish is present.
  6. A plain Markdown file without frontmatter is treated as published content.
  7. output/ contains generated artifacts and must not be used as source content.

The directory names can be changed with pages_path, posts_path, content_dir, templates_dir, data_dir, static_dir and output_dir.

Frontmatter reference

For predictable results, pages and posts should define title, status and type. Posts should additionally define date.

Field Type Meaning
title string Display title
slug string URL segment; defaults to the Markdown filename
status string Only publish is rendered when frontmatter exists
type string page or post; affects templates and URL generation
date date Post publication date in YYYY-MM-DD form
modified date Last modification date
categories list Category IDs, names or slugs from metadata.json
author integer/string Author ID, name or slug from metadata.json
tags list Free-form tags; generates /tag/<slug>/ listings
series string Generates a /series/<slug>/ listing and navigation
excerpt string Summary for listings, feeds and metadata
description string SEO description; falls back to the excerpt
link string Explicit URL path; overrides normal URL rules
canonical string Explicit canonical URL
aliases list Previous paths that 301 to this item (and, by default, get a redirect stub)
alias_stubs bool Per-page override: false = 301 only (no duplicate copy), true = force a stub
schema map Override/extend this page's generated JSON-LD (deep-merged, per-page wins)
featured_image string Hero image; also the og:image, twitter:image and JSON-LD image (follows WebP conversion)
layout string Page layout name; redirect also marks sitemap exclusion
template string Page template file override
robots string Robots directive; noindex also excludes from sitemap
sitemap string Set to no to exclude from sitemap.xml
lang string Content language for multilingual builds

Unknown frontmatter keys are preserved and exposed to templates. Author and category matching is case-insensitive; unresolved values are ignored.

Excerpts

Markdown can use explicit export-style sections:

## Excerpt
A short description used in listings.

## Content
The complete article starts here.

Without these exact markers, all Markdown after the frontmatter becomes content.

Configuration

SSG automatically detects .ssg.yaml, .ssg.toml or .ssg.json:

ssg

An explicit file can be selected with:

ssg --config path/to/site.yaml

Minimal .ssg.yaml:

source: my-blog
template: simple
domain: example.com

clean: true
minify_all: true

Common options:

Goal Configuration key CLI flag
Development server http: true --http
Automatic rebuilds watch: true --watch
Cloudflare Wrangler watch_runner: wrangler --wrangler
Cloudflare Workerd watch_runner: workerd --workerd
Custom watch command watch_runner: "cmd" --watch-runner="cmd"
Runner config outside the project watch_runner_config: deploy/wrangler.toml --wrangler-config=deploy/wrangler.toml
Worker in a monorepo subdirectory watch_runner_dir: booking/apps/api --wrangler-dir=booking/apps/api
Clean output first clean: true --clean
Minify HTML/CSS/JS minify_all: true --minify-all
Convert images to WebP webp: true --webp
Responsive images image_sizes: [480, 960] --image-sizes=480,960
Fingerprint CSS/JS fingerprint: true --fingerprint
Compile SCSS scss: true --scss
Generate Atom feeds feed: true --feed
Generate search index search_index: true --search-index
Declare the site's tools to a browser agent webmcp: true --webmcp
Add SEO metadata seo: true --seo
Validate frontmatter contracts content_schemas: {post: {required: [title, date]}} config only
Fail the build on any violation strict: true --strict
Emit a route manifest (routes.json) route_manifest: true --route-manifest
Publish a build report (version, duration, pages) build_report: build.json --build-report
Publish the site's model for agents (site-graph.json + MCP site_*) site_graph: true config only
Report where the build's time went profile: text --profile[=json]
Rebuild only what a change reaches incremental: true --incremental
Keep converted Markdown between builds markdown_cache: true --markdown-cache
See what a change rebuilds, and why — ssg graph [file], MCP site_dependencies
Read and edit the config from the CLI — ssg config view|set|unset
Turn records from a file or API into pages mode: content + content_map: config only
Edit frontmatter and body text in the browser, with AI proposals that never save — --http --watch --edit
Declare tracking ids (GTM both halves, GA4) analytics_ids: {gtm: GTM-…} config only
Typed content components with a props schema a components/ directory --components-dir=DIR
Decide the markup for images, links, headings, code render_hooks: {image: …} config only
Name relations between pages, and version a document relations: / version_of: in frontmatter config only
Publish a page as JSON, Markdown, text or your own format outputs: {page: [html, json]} --outputs=html,json
Validate internal links check_links: strict --check-links=strict
Fail on unrenderable shortcodes shortcode_errors: strict --shortcode-errors=strict
Pull Markdown from other folders content_sources: [{path: docs}] --content-source=docs
Derive missing excerpts auto_excerpt: true --auto-excerpt
Rewrite links to repository files link_rewrites: {"../examples/": "https://…"} config only
Create ZIP package zip: true --zip

WebP output requires the optional cwebp executable. SCSS compilation requires the optional Dart Sass sass executable. Other native image operations use Go, but selecting WebP as their output format also requires cwebp.

The canonical configuration reference is .ssg.yaml.example. The CLI also provides an installed-version reference:

ssg --help

Common recipes

Task Command
Preview while editing ssg my-blog simple example.com --http --watch
Let a client edit a page in the browser ssg my-blog simple example.com --http --watch --edit
See what editing one file rebuilds ssg graph content/my-blog/posts/hello.md
Production build ssg my-blog simple example.com --clean --minify-all
WebP and responsive images ssg my-blog simple example.com --webp --image-sizes=480,960,1600
Feed, search and SEO ssg my-blog simple example.com --feed --search-index --seo
Immutable asset names ssg my-blog simple example.com --minify-all --fingerprint
Strict link validation ssg my-blog simple example.com --check-links=strict
Create deployment archives ssg my-blog simple example.com --zip --targz --tarxz
Use a Pongo2 theme ssg my-blog my-theme example.com --engine=pongo2
Use only configuration ssg --config .ssg.yaml

Options are composable unless a specific option documents otherwise.

Capability map

This is a discovery index, not a second configuration reference. Exact defaults and accepted values live in .ssg.yaml.example.

Area Available capabilities
Authoring Shortcodes, table of contents, syntax highlighting, KaTeX math, raw HTML sanitization; a file dropped for a missing status: or unparseable frontmatter is named with the likely cause (strict: true fails the build on the latter) (docs/CONTENT.md)
Blog Pagination, tags, categories, series, reading time, Atom feeds, related content
API docs from code api_docs: reads JavaScript (and TypeScript declarations) with their doc comments into pages of the site — packages, modules, classes, cross-links, source links — plus api.json, check_api, and MCP/WebMCP tools for agents; no Node needed for JS. @example blocks can run in the browser (playground:) (docs/API_DOCS.md)
API docs for Go, PHP, Python The same pages from Go (standard library parser), PHP and Python (built-in declaration scanners): nothing to install, language detected from go.mod, composer.json, pyproject.toml (docs/API_LANGUAGES.md)
Web Stories Google Web Stories (AMP) from your posts: cover, captioned photo pages, a link back to the article, a hub page and sitemap entries (docs/WEB_STORIES.md)
Print / PDF and Cook Mode A print button with a clean print stylesheet and a printable recipe card, and a full-screen step-by-step recipe view that keeps the screen awake; every theme, built from the Recipe structured data (docs/PRINT_AND_COOK_MODE.md)
Résumé / CV A Schema Resume JSON document as a page in any theme, with ProfilePage/Person JSON-LD and the document at /cv/resume.json; contact details stay private by default (docs/RESUME.md)
Recipes and structured data Recipe fields from the post (ingredients, method, category), faq: → FAQPage, ItemList on listings, ProfilePage for authors, Organization from marketing: (docs/CONFIGURATION.md)
REST API docs from OpenAPI api_docs: - openapi: openapi.yaml turns an OpenAPI 3.0/3.1 file into pages: endpoints by tag, parameters, bodies, responses, schemas, and a "Try it" console that sends real requests with keys kept in memory only (docs/REST_API_DOCS.md)
apidoc theme A documentation-only theme: guides and references in one sidebar, search, "On this page", light/dark, WCAG 2.2 AA (templates/apidoc/README.md)
Read aloud A "Listen" button with the visitor's own browser voice, and/or an MP3 per article from a TTS API at build time — cached, with a jingle, a fallback when the API is down, a podcast feed, and a self-hostable Docker TTS server (docs/AUDIO.md)
Taxonomies Custom dynamic taxonomies with term archives, metadata, per-term feeds and template helpers (docs/TAXONOMIES.md)
SEO and migration Sitemap, robots.txt, aliases, configurable permalinks, canonical URLs, link checking, .md link rewriting
Site migration ssg migrate wordpress <url> — scaffold + content pull (wpexporter) + build in one command; completes title/description/timezone/colors from the source site; pages, posts, media, a theme's own post types and reader comments; --watch --http migrates live in the browser (docs/MIGRATE.md)
Front page A content page at / (what a WordPress static front page exports as) becomes the site's front page; posts_page: gives the generated listing a home of its own
Content repair ssg repair --fix rewrites source Markdown a page-builder export left indented or fenced into a code block; check_markup reports both on every build (docs/CONFIGURATION.md)
Several projects at once ssg daemon watches every project in .ssg_projects from one process; editing the file reloads the fleet in place, leaving untouched projects running (docs/DAEMON.md)
Staying current Every build's first line names the binary that produced it; ssg self-update-check says whether a newer release is out and prints the upgrade command for your install — snap, Homebrew, apt, dnf, Docker or the releases page. It never self-updates and never contacts the network on its own (docs/INSTALL.md)
Redirects redirects: → real Cloudflare/Netlify _redirects (splats, chain flattening, aliases as 301s), served by the built-in preview so a rule can be checked before it ships, ssg import redirects from a JS redirects() config (docs/DEPLOYMENT.md)
Dynamic endpoints Cloudflare Pages Functions via worker: + ssg new worker templates (contact form, Stripe, dynamic pricing, conversions proxy, cookie consent, comments, newsletter sign-up, rate limit, republish trigger), configurable _headers (docs/WORKERS.md)
Assets WebP, responsive variants, build-time image helpers, SCSS, bundles, minification, source maps, fingerprinting
Data YAML/JSON data files, custom variables and static passthrough files
External sources Unified .ExternalData from local files (YAML/JSON/TOML/CSV/XML), HTTP APIs with a hardened client + disk cache, read-only SQL (MySQL/MariaDB/PostgreSQL/SQLite) and CMS imports (WordPress, Drupal, Movable Type) (docs/EXTERNAL_SOURCES.md)
Localisation Full i18n: translation keys, dictionaries + t, language routing, hreflang/x-default in the head and in the sitemap (front pages and post listings included), per-language feeds each advertised on its own language's pages, search, language_sections: to assign a language to a whole directory, upper/lower/title for a switcher's labels (docs/I18N.md)
Content sources Local Markdown or MDDB over HTTP/gRPC, including watched remote content
Output Directory/flat pages, JSON output, feeds, search index, ZIP, tar.gz and tar.xz
Server File watching, gzip, TLS, automatic certificates, HTTP/2, HTTP/3, resource limits, basic/JWT auth, IP allow/block lists and per-IP rate limiting
Automation Lifecycle hooks, Git-derived modification dates, GitHub Action and native deployment
AI assistance Build-time [ai …] shortcode (models + agents with rules/skills, cached answers), ssg mcp development server with designer and content-manager roles, find-then-edit tools that cost the size of the change rather than the file, an optional MDDB-backed search, and an approve-then-PR git flow (docs/MCP.md)

Templates

Engines

Engine Value Syntax family
Go templates go Go html/template; default and full helper support
Pongo2 pongo2 Jinja2/Django
Mustache mustache Logic-less Mustache
Handlebars handlebars Handlebars blocks and helpers

Select an engine with --engine=<value> or engine: <value>. Non-Go themes must contain templates authored in their selected syntax; they do not receive the Go template FuncMap or Go block inheritance.

Theme files

A typical Go theme contains:

templates/my-theme/
├── base.html
├── index.html
├── page.html
├── post.html
├── category.html
├── css/
├── js/
├── layouts/
└── partials/

Missing standard templates receive built-in fallbacks. Themes may also be downloaded with --online-theme=<URL>.

Common Go template values:

Value Meaning
.Title, .Content, .Excerpt Current page/post content
.URL, .CanonicalURL Relative and canonical URLs
.Date, .Modified Content dates
.Site.Pages, .Site.Posts Site collections
.Data Data loaded from data/
.Vars Custom configuration variables
.Pager Pagination state when enabled

For collection helpers, conditionals and image functions, see docs/TEMPLATE_HELPERS.md and docs/IMAGES.md.

Generated output

Depending on enabled features, output/ can contain:

output/
├── index.html
├── <page-slug>/index.html
├── <year>/<month>/<day>/<post-slug>/index.html
├── category/<category-slug>/index.html
├── tag/<tag-slug>/index.html
├── series/<series-slug>/index.html
├── css/
├── js/
├── media/
├── sitemap.xml
├── robots.txt
├── feed.xml
└── search-index.json

URL layouts can be changed with page_format, post_url_format, explicit permalink patterns or an item's link field.

Deployment

SSG can deploy the generated output without provider-specific CLIs. Credentials are read from environment variables, never from content files.

Provider Flag Required environment
Cloudflare Pages --deploy=cloudflare CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID
GitHub Pages --deploy=github-pages GITHUB_TOKEN or SSH credentials
Netlify --deploy=netlify NETLIFY_AUTH_TOKEN
Vercel --deploy=vercel VERCEL_TOKEN (optional VERCEL_ORG_ID for team scope)
FTP --deploy=ftp FTP_USERNAME, FTP_PASSWORD
SFTP --deploy=sftp SSH_USERNAME + SSH_PASSWORD or SSH_KEY_FILE

Example:

CLOUDFLARE_API_TOKEN=... CLOUDFLARE_ACCOUNT_ID=... \
  ssg my-blog simple example.com \
  --deploy=cloudflare --deploy-project=my-site

Deployment runs after generation and post-processing.

GitHub Actions

name: Build site

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: spagu/ssg@v1
        with:
          source: my-blog
          template: simple
          domain: example.com
          clean: "true"
          minify: "true"

For a site configured by .ssg.yaml — redirects, workers, variables — point the action at the file instead; source/template/domain then come from it:

      - uses: spagu/ssg@v1
        with:
          config: .ssg.yaml
          deploy: cloudflare
          deploy-project: my-site

All supported inputs and outputs are defined in action.yml. Deployment workflow examples are available in examples/workflows.

Development

Building SSG itself requires Go 1.27.3 or newer — the version the go directive in go.mod asks for. 1.27.2 carries GO-2026-6809 (crypto/x509), which ssg reaches through every TLS connection. The floor was 1.26.6 before 1.27, because earlier Go 1.26 releases contain standard-library vulnerabilities relevant to this project.

git clone https://github.com/spagu/ssg.git
cd ssg
make all

Useful targets — make help lists every one of them:

Command Purpose
make build Build build/ssg
make build-all Cross-compile for Linux, macOS, Windows, FreeBSD and OpenBSD
make install / make uninstall Install or remove the binary and its man page
make test Run tests
make test-coverage Run tests and generate coverage
make lint Run static checks
make security Run security scanners
make golden Check generated output against the recorded baseline
make golden-update Re-record the baseline after an intended output change
make determinism Check the worker count does not change the output
make bench Measure build throughput on a synthetic corpus
make site Build this project's own documentation site into .site/
make site-watch Serve the documentation site and rebuild on change
make site-edit The same, with the browser editor on — edits land on a branch
make version-check Fail if any packaging file drifts from VERSION
make version-sync Propagate VERSION into every file that states it
make package-all Build the DEB, RPM and Snap packages
make release VERSION=v1.2.3 Tag and push a release

CI holds a 96% statement-coverage floor twice: on the module as a whole and on every package individually, both computed without the generated protobuf. A pull request that drops either fails the Test job — see CONTRIBUTING.md for the exact check and how to run it locally. BENCH_INCREMENTAL=1 make bench times a one-post edit under --incremental beside a full build. | make all | Dependencies, lint, tests and build | | make install | Install the binary and manual page |

make golden and make determinism guard the two properties the test suite cannot express as unit tests: that a change did not alter generated output, and that parallel rendering produces the same site as a sequential build. Both run in CI. After an intended output change, re-record the baseline with make golden-update and commit it.

Development workflow and review requirements are in CONTRIBUTING.md. Please follow CODE_OF_CONDUCT.md. Existing contributors are listed in CONTRIBUTORS.md.

Documentation

Document Scope
.ssg.yaml.example Complete configuration reference
docs/INSTALL.md Platform installation guide
docs/API_DOCS.md API documentation from JavaScript/TypeScript code: configuration, doc comments, links, live examples, themes, api.json, agents
docs/API_LANGUAGES.md API docs for Go, PHP and Python: what each reader understands and its limits
docs/WEB_STORIES.md Google Web Stories from posts: what is generated, images, theming, validation
docs/PRINT_AND_COOK_MODE.md The Print / PDF button, the printable recipe card and Cook Mode
docs/RESUME.md A CV from a Schema Resume document: page, structured data, privacy
docs/REST_API_DOCS.md REST API documentation from OpenAPI: pages, the Try it console, checks, theming
docs/AUDIO.md Articles read aloud: the browser button, build-time MP3 through a TTS API, the podcast feed
services/tts-server/README.md Self-hosted TTS API (Docker, Swagger, espeak-ng and Piper voices) that ssg's generic provider talks to
docs/MCP.md MCP server for AI agents: roles, tools, find-then-edit, MDDB search, git write-back
docs/RENDER_HOOKS.md Render hooks: responsive images for content, an external-link policy, wrapping code blocks
docs/COMPONENTS.md Typed content components: the props schema, the call syntax, assets per page, components.json
docs/INCREMENTAL.md --incremental and ssg graph: what a change rebuilds, when a build is full anyway, what it saves
docs/EDITING.md --edit: editing frontmatter in the browser — what a theme marks, where a save goes, the security rules
docs/UPGRADING.md Version-to-version upgrade steps, with a picker for your current version
docs/CONTENT.md Content structure, frontmatter and URL rules
docs/MIGRATE.md ssg migrate: providers, content selection, live --watch --http mode
docs/DAEMON.md ssg daemon: several projects watched by one process, reloaded in place
docs/MCP_TRANSPORTS.md ssg mcp over stdio and Streamable HTTP, and how to expose it safely
docs/CONFIGURATION.md Configuration and advanced feature guide
docs/I18N.md Internationalisation: translations, dictionaries, language routing
docs/TAXONOMIES.md Dynamic taxonomies: definitions, term metadata, archives, helpers
docs/EXTERNAL_SOURCES.md External data: files, HTTP APIs, SQL, CMS imports, cache, security
docs/TEMPLATES.md Theme files, engines and rendering contexts
docs/TEMPLATE_HELPERS.md Go template helper reference
docs/IMAGES.md Build-time image processing
docs/DEPLOYMENT.md Native providers, archives and GitHub Actions
docs/STYLES.md Built-in theme style guide
examples/README.md Example projects and workflows
CONTRIBUTING.md Development and contribution workflow
CHANGELOG.md Release history and migration notes
SECURITY.md Vulnerability reporting policy

Three posts cover 1.8.60 for the people who maintain client sites: what an agency does between builds, what breaks if I change this and the paragraph you clicked is not in the file.

The project blog also covers the reasoning behind recent MCP work, including smaller context for targeted edits authentication for HTTP MCP, preserving URLs during WordPress migration and deployment-aware local preview.

License

SSG is distributed under the BSD 3-Clause License.

About

A simple static site generator written in Go. Converts content from WordPress exports (Markdown format with YAML frontmatter) to static HTML, CSS, and JS files.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

4 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages