Static Site Build
The accent build command generates a directory of static HTML, CSS, and assets that can be served by any web server or hosting provider. Static builds are free – no license key is required.
The accent build Command
accent build --output ./public --base-url https://example.com
Flags
| Flag | Description | Default |
|---|---|---|
--output / -o | Output directory for generated files | output |
--base-url | Base URL for absolute links and sitemaps | (none; falls back to site.url) |
--config / -c | Path to config file | ./config.yaml |
--clean | Remove output directory before building | false |
The --base-url flag is important for production builds. It sets the base for absolute URLs in sitemaps, RSS feeds, and canonical links. Always set it to your production domain.
Output Directory Structure
A typical build produces the following:
public/
index.html # Home page
about/
index.html # About page
blog/
index.html # Blog listing (page 1)
page/
2/index.html # Blog listing (page 2)
my-first-post/
index.html # Blog post
docs/
index.html # Docs index
getting-started/
index.html
feed.xml # RSS feed
sitemap.xml # XML sitemap
robots.txt # Robots configuration
assets/ # Theme CSS, JS, and images
css/
style.css
js/
main.js
media/ # Pre-processed media files
blog/
my-first-post/
hero.webp
hero-thumb.webp
Every page becomes an index.html inside a directory matching its URL path. This produces clean URLs without file extensions on any web server.
You may also see small *.md/index.html files (e.g. blog.md/index.html) next to the real pages. These are redirect stubs that bounce GitHub-style .md links to the clean URL; each is a meta-refresh with a canonical link, and they are excluded from sitemap.xml and feed.xml. To omit them, set content.md_extension_redirects: false in config.yaml.
Preview with serve-static
Before deploying, preview the build output locally using serve-static:
accent build --output ./public --base-url https://example.com accent serve-static --dir ./public # Visit http://127.0.0.1:4403
To preview over HTTPS (useful for testing service workers or mixed-content policies):
accent serve-static --dir ./public --tls # Visit https://127.0.0.1:4403 (accept the self-signed certificate warning)
This is especially useful in CI pipelines for running smoke tests against the built output before deploying.
Deploy to Cloudflare Pages
Cloudflare Pages provides free hosting with a global CDN. Deploy with GitHub Actions:
# .github/workflows/deploy.yml name: Deploy to Cloudflare Pages on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Install Accent CMS run: | curl -fsSL https://accentcms.dev/install.sh | sh echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Build site run: accent build --output ./public --base-url ${{ vars.SITE_URL }} - name: Deploy uses: cloudflare/wrangler-action@v3 with: command: pages deploy ./public --project-name=my-site apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
Set SITE_URL as a repository variable and CLOUDFLARE_API_TOKEN as a repository secret in your GitHub settings.
Deploy to Netlify
Create a netlify.toml in your project root:
[build]
command = "accent build --output ./public --base-url https://example.com"
publish = "public"
[build.environment]
# Netlify will use this to install Accent CMS
ACCENTCMS_VERSION = "latest"
[[redirects]]
from = "/*"
to = "/404.html"
status = 404
Alternatively, deploy with the Netlify CLI:
accent build --output ./public --base-url https://your-site.netlify.app npx netlify deploy --prod --dir=./public
Deploy to GitHub Pages
Use GitHub Actions to build and deploy to GitHub Pages:
# .github/workflows/pages.yml name: Deploy to GitHub Pages on: push: branches: [main] permissions: contents: read pages: write id-token: write jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Install Accent CMS run: | curl -fsSL https://accentcms.dev/install.sh | sh echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Build site run: accent build --output ./public --base-url https://username.github.io/repo - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: path: ./public deploy: needs: build runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4
Enable GitHub Pages in your repository settings under Settings > Pages and select GitHub Actions as the source.
Deploy to Vercel
Create a vercel.json in your project root:
{ "buildCommand": "accent build --output ./public --base-url https://example.vercel.app", "outputDirectory": "public", "cleanUrls": true }
Deploy with the Vercel CLI:
npx vercel --prod
Deploy to Any Web Server
Copy the public/ directory to the document root of any web server:
accent build --output ./public --base-url https://example.com # Copy to a remote server rsync -avz --delete ./public/ user@server:/var/www/example.com/ # Or serve locally with nginx sudo cp -r ./public/* /var/www/html/
nginx Configuration for Static Files
server {
listen 80;
server_name example.com;
root /var/www/example.com;
# Clean URLs: try directory index first
location / {
try_files $uri $uri/index.html =404;
}
# Cache static assets aggressively
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Custom 404 page
error_page 404 /404.html;
}
Caddy Configuration
example.com {
root * /var/www/example.com
file_server
try_files {path} {path}/index.html
}
Differences from Dynamic Serving
The static build output is functionally identical to what the dynamic server renders, with a few differences:
| Aspect | Dynamic Server | Static Build |
|---|---|---|
| Pagination | Rendered on request | Physical page/N/index.html files |
| Plugins | Execute at request time | Execute once at build time |
| Media processing | On-demand (first request triggers processing) | All media pre-processed at build time |
| Content updates | Edit file, refresh browser | Edit file, rebuild, redeploy |
| Config changes | SIGHUP to reload, or restart | Rebuild required |
| RSS/Sitemap | Generated on request | Generated as static files |
Templates, markdown rendering, and page output are identical between the two modes.
CI/CD Pipeline Example
A complete GitHub Actions workflow that builds, tests, and deploys:
# .github/workflows/deploy.yml name: Build and Deploy on: push: branches: [main] pull_request: branches: [main] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Install Accent CMS run: | curl -fsSL https://accentcms.dev/install.sh | sh echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Validate content run: accent validate - name: Build site run: accent build --output ./public --base-url ${{ vars.SITE_URL }} - name: Check for broken links run: | npx broken-link-checker-local ./public --recursive - name: Deploy (main branch only) if: github.ref == 'refs/heads/main' && github.event_name == 'push' run: | # Replace with your deployment command rsync -avz --delete ./public/ user@server:/var/www/site/
Pull requests run the build and validation steps without deploying, so you can catch issues before merging.
Next Steps
- Production Server – run Accent CMS as a dynamic service
- Deployment Overview – compare deployment strategies
- Getting Started – initial project setup