Every Statik project is driven by a config.json file located at the project root. This document describes each configuration option available.

Example config.json

{
  "siteName": "My Website",
  "description": "A website built with Statik",
  "baseUrl": "https://mysite.com",
  "author": "Your Name",
  "theme": {
    "templates": "templates",
    "assets": "static",
    "output": "build"
  },
  "paths": {
    "posts": "posts",
    "pages": "content"
  },
  "devServer": {
    "port": 3000
  },
  "staticDatasource": {
    "enabled": true,
    "outputDir": "datasource",
    "collectAttribute": "data-collect",
    "imagesFileName": "images.json",
    "configFile": "datasource-config.json"
  },
  "rss": {
    "enabled": true,
    "fileName": "feed.xml",
    "title": "My Website RSS Feed",
    "description": "Latest posts from my website",
    "language": "en-us",
    "maxItems": 20,
    "includeFullContent": true
  }
}

Configuration Options

core

description required

Type:
string
EntityDatasourceItem(dataset=api, id=api-description, title=description, content=

Default site description applied to templates, meta tags, and RSS feeds when individual pages don't provide their own.

, metadata={title=description, type=string, required=true, default=null, category=core, order=3}, source=DatasourceItemSource(type=api, id=api-description, path=/api/description/, title=description))

siteName required

Type:
string
EntityDatasourceItem(dataset=api, id=api-siteName, title=siteName, content=

Display name used across templates and metadata. This appears in page titles, RSS feeds, and anywhere {{siteName}} is referenced.

, metadata={title=siteName, type=string, required=true, default=null, category=core, order=1}, source=DatasourceItemSource(type=api, id=api-siteName, path=/api/siteName/, title=siteName))

author required

Type:
string
EntityDatasourceItem(dataset=api, id=api-author, title=author, content=

Author attribution used in templates and metadata. Can be referenced via {{author}} in Handlebars templates.

, metadata={title=author, type=string, required=true, default=null, category=core, order=4}, source=DatasourceItemSource(type=api, id=api-author, path=/api/author/, title=author))

baseUrl required

Type:
string
EntityDatasourceItem(dataset=api, id=api-baseUrl, title=baseUrl, content=

Fully qualified site URL (e.g., https://mysite.com). Statik uses this for canonical links, RSS feed URLs, and absolute path generation.

, metadata={title=baseUrl, type=string, required=true, default=null, category=core, order=2}, source=DatasourceItemSource(type=api, id=api-baseUrl, path=/api/baseUrl/, title=baseUrl))

theme

theme.output

Type:
string
Default:
build
EntityDatasourceItem(dataset=api, id=api-theme.output, title=theme.output, content=

Build directory that receives generated HTML, copied assets, and datasource JSON files.

, metadata={title=theme.output, type=string, required=false, default=build, category=theme, order=3}, source=DatasourceItemSource(type=api, id=api-theme.output, path=/api/theme.output/, title=theme.output))

theme.assets

Type:
string
Default:
static
EntityDatasourceItem(dataset=api, id=api-theme.assets, title=theme.assets, content=

Directory for static files (CSS, JS, images) copied verbatim to the build output.

, metadata={title=theme.assets, type=string, required=false, default=static, category=theme, order=2}, source=DatasourceItemSource(type=api, id=api-theme.assets, path=/api/theme.assets/, title=theme.assets))

theme.templates

Type:
string
Default:
templates
EntityDatasourceItem(dataset=api, id=api-theme.templates, title=theme.templates, content=

Directory containing Handlebars templates and layouts. See Layouts documentation for template structure and organization.

, metadata={title=theme.templates, type=string, required=false, default=templates, category=theme, order=1, link=/layouts}, source=DatasourceItemSource(type=api, id=api-theme.templates, path=/api/theme.templates/, title=theme.templates))

Learn more →

paths

paths.pages

Type:
string
Default:
pages
EntityDatasourceItem(dataset=api, id=api-paths.pages, title=paths.pages, content=

Location of standalone pages. Pages support navigation ordering via nav_order frontmatter field.

, metadata={title=paths.pages, type=string, required=false, default=pages, category=paths, order=2}, source=DatasourceItemSource(type=api, id=api-paths.pages, path=/api/paths.pages/, title=paths.pages))

paths.posts

Type:
string
Default:
posts
EntityDatasourceItem(dataset=api, id=api-paths.posts, title=paths.posts, content=

Location of blog post content. Supports Markdown (.md), HTML (.html), and Handlebars (.hbs) files with YAML frontmatter.

, metadata={title=paths.posts, type=string, required=false, default=posts, category=paths, order=1}, source=DatasourceItemSource(type=api, id=api-paths.posts, path=/api/paths.posts/, title=paths.posts))

devServer

devServer.port

Type:
number
Default:
3000
EntityDatasourceItem(dataset=api, id=api-devServer.port, title=devServer.port, content=

Port for the development server launched with --watch mode. Change if port 3000 conflicts with another service.

, metadata={title=devServer.port, type=number, required=false, default=3000, category=devServer, order=1}, source=DatasourceItemSource(type=api, id=api-devServer.port, path=/api/devServer.port/, title=devServer.port))

staticDatasource

staticDatasource.collectAttribute

Type:
string
Default:
data-collect
EntityDatasourceItem(dataset=api, id=api-staticDatasource.collectAttribute, title=staticDatasource.collectAttribute, content=

HTML attribute marking custom collectable elements in content. See Static Datasources for collection patterns.

, metadata={title=staticDatasource.collectAttribute, type=string, required=false, default=data-collect, category=staticDatasource, order=3, link=/static-datasources}, source=DatasourceItemSource(type=api, id=api-staticDatasource.collectAttribute, path=/api/staticDatasource.collectAttribute/, title=staticDatasource.collectAttribute))

Learn more →

staticDatasource.configFile

Type:
string
Default:
datasource-config.json
EntityDatasourceItem(dataset=api, id=api-staticDatasource.configFile, title=staticDatasource.configFile, content=

Location of dataset definitions for entity folders and metadata-tagged content. See Static Datasources for configuration schema.

, metadata={title=staticDatasource.configFile, type=string, required=false, default=datasource-config.json, category=staticDatasource, order=5, link=/static-datasources}, source=DatasourceItemSource(type=api, id=api-staticDatasource.configFile, path=/api/staticDatasource.configFile/, title=staticDatasource.configFile))

Learn more →

staticDatasource.outputDir

Type:
string
Default:
datasource
EntityDatasourceItem(dataset=api, id=api-staticDatasource.outputDir, title=staticDatasource.outputDir, content=

Folder inside the build directory where datasource JSON files are written. See Static Datasources.

, metadata={title=staticDatasource.outputDir, type=string, required=false, default=datasource, category=staticDatasource, order=2, link=/static-datasources}, source=DatasourceItemSource(type=api, id=api-staticDatasource.outputDir, path=/api/staticDatasource.outputDir/, title=staticDatasource.outputDir))

Learn more →

staticDatasource.enabled

Type:
boolean
Default:
true
EntityDatasourceItem(dataset=api, id=api-staticDatasource.enabled, title=staticDatasource.enabled, content=

Enable or disable static datasource generation. See Static Datasources for usage patterns.

, metadata={title=staticDatasource.enabled, type=boolean, required=false, default=true, category=staticDatasource, order=1, link=/static-datasources}, source=DatasourceItemSource(type=api, id=api-staticDatasource.enabled, path=/api/staticDatasource.enabled/, title=staticDatasource.enabled))

Learn more →

staticDatasource.imagesFileName

Type:
string
Default:
images.json
EntityDatasourceItem(dataset=api, id=api-staticDatasource.imagesFileName, title=staticDatasource.imagesFileName, content=

Filename for the auto-generated images datasource. See Static Datasources for image collection details.

, metadata={title=staticDatasource.imagesFileName, type=string, required=false, default=images.json, category=staticDatasource, order=4, link=/static-datasources}, source=DatasourceItemSource(type=api, id=api-staticDatasource.imagesFileName, path=/api/staticDatasource.imagesFileName/, title=staticDatasource.imagesFileName))

Learn more →

rss

rss.includeFullContent

Type:
boolean
Default:
true
EntityDatasourceItem(dataset=api, id=api-rss.includeFullContent, title=rss.includeFullContent, content=

When true, embeds full HTML post content in feed items. Set to false for excerpt-only feeds.

, metadata={title=rss.includeFullContent, type=boolean, required=false, default=true, category=rss, order=7}, source=DatasourceItemSource(type=api, id=api-rss.includeFullContent, path=/api/rss.includeFullContent/, title=rss.includeFullContent))

rss.enabled

Type:
boolean
Default:
true
EntityDatasourceItem(dataset=api, id=api-rss.enabled, title=rss.enabled, content=

Toggle RSS feed generation. When enabled, creates an RSS 2.0 feed of recent posts.

, metadata={title=rss.enabled, type=boolean, required=false, default=true, category=rss, order=1}, source=DatasourceItemSource(type=api, id=api-rss.enabled, path=/api/rss.enabled/, title=rss.enabled))

rss.maxItems

Type:
number
Default:
20
EntityDatasourceItem(dataset=api, id=api-rss.maxItems, title=rss.maxItems, content=

Maximum number of recent posts to include in the RSS feed.

, metadata={title=rss.maxItems, type=number, required=false, default=20, category=rss, order=6}, source=DatasourceItemSource(type=api, id=api-rss.maxItems, path=/api/rss.maxItems/, title=rss.maxItems))

rss.description

Type:
string
Default:
none
EntityDatasourceItem(dataset=api, id=api-rss.description, title=rss.description, content=

Feed description. Defaults to site description if not provided.

, metadata={title=rss.description, type=string, required=false, default=null, category=rss, order=4}, source=DatasourceItemSource(type=api, id=api-rss.description, path=/api/rss.description/, title=rss.description))

rss.fileName

Type:
string
Default:
feed.xml
EntityDatasourceItem(dataset=api, id=api-rss.fileName, title=rss.fileName, content=

Output filename for the RSS feed, placed in the build root directory.

, metadata={title=rss.fileName, type=string, required=false, default=feed.xml, category=rss, order=2}, source=DatasourceItemSource(type=api, id=api-rss.fileName, path=/api/rss.fileName/, title=rss.fileName))

rss.title

Type:
string
Default:
none
EntityDatasourceItem(dataset=api, id=api-rss.title, title=rss.title, content=

Feed title. Defaults to siteName if not provided.

, metadata={title=rss.title, type=string, required=false, default=null, category=rss, order=3}, source=DatasourceItemSource(type=api, id=api-rss.title, path=/api/rss.title/, title=rss.title))

rss.language

Type:
string
Default:
en-us
EntityDatasourceItem(dataset=api, id=api-rss.language, title=rss.language, content=

RSS language code (e.g., en-us, fr-fr). Used in the feed's <language> element.

, metadata={title=rss.language, type=string, required=false, default=en-us, category=rss, order=5}, source=DatasourceItemSource(type=api, id=api-rss.language, path=/api/rss.language/, title=rss.language))

Debug Helper

Type:
EntityDatasourceItem(dataset=api, id=api-debug, title=Debug Helper, content=

Debug Helper

The {{debug}} helper is a powerful debugging tool that displays all available template variables and their nested properties in your Handlebars templates.

Usage

Simply add {{debug}} anywhere in your template:

<h1>{{title}}</h1>
{{debug}}
<p>{{content}}</p>

Output

The debug helper will render a styled <pre> block showing:

  • All available variables in the current template context
  • Nested properties up to 3 levels deep
  • Lists with their first 3 items
  • Object properties and their types

Example output:

Debug: Template Variables
════════════════════════════════════════════════════════════
count: 42
enabled: true
post: {3 properties}
  date: "2025-11-22"
  tags: [3 items]
    [0]: "kotlin"
    [1]: "handlebars"
    [2]: "debug"
  title: "Post Title"
title: "My Post"
════════════════════════════════════════════════════════════

Features

  • Automatic nesting: Shows nested objects and their properties up to 3 levels deep
  • List inspection: Displays the first 3 items of any list/array
  • Type information: Shows the type of complex objects
  • Truncation: Long strings (>100 chars) are truncated with "..." for readability
  • Sorted keys: Variables are displayed alphabetically for easy scanning
  • Styled output: Renders in a fixed-width, scrollable box with a max height of 600px

Use Cases

  • Template debugging: See what data is available in your template context
  • Development: Understand the structure of posts, pages, and custom data
  • Troubleshooting: Verify that expected variables are present and have correct values

Common Issues Revealed by Debug

Tags Not Rendering Correctly

If you see strange output when iterating over tags (like isEmpty, hashCode, byte arrays, etc.), you're likely iterating over page.metadata.tags or post.metadata.tags, which are strings, not arrays.

Wrong:

{{#each page.metadata.tags}}  <!-- This is a string! -->
  <span>{{this}}</span>
{{/each}}

Correct:

{{#each page.tags}}  <!-- This is a proper array -->
  <span>{{this}}</span>
{{/each}}

Both BlogPost and SitePage have a tags property that automatically parses the comma-separated string from metadata into a list.

Notes

  • The debug helper is safe to use in production, but you should remove it before deploying
  • The output is HTML-formatted and won't be escaped by Handlebars
  • Variables starting with __ (internal variables) may be present in the context
, metadata={title=Debug Helper, layout=default}, source=DatasourceItemSource(type=api, id=api-debug, path=/api/debug/, title=Debug Helper))

Metadata Properties

Type:
EntityDatasourceItem(dataset=api, id=api-metadata-properties, title=Metadata Properties, content=

Metadata Properties

Both BlogPost and SitePage objects automatically parse common metadata fields into convenient properties that you can use directly in your templates.

Tags

Tags are automatically parsed from comma-separated values in the frontmatter into a list.

Frontmatter:

---
title: "My Post"
tags: "kotlin, web, tutorial"
---

Template usage:

{{#if post.tags}}
<div class="tags">
  {{#each post.tags}}
  <span class="tag">{{this}}</span>
  {{/each}}
</div>
{{/if}}

Important: Always use post.tags or page.tags, NOT post.metadata.tags or page.metadata.tags. The metadata value is a string, which will cause issues when iterating with {{#each}}.

Summary

The summary property is the primary field for content summaries.

For BlogPost

<p class="post-summary">{{post.summary}}</p>

Priority:

  1. metadata["summary"] - Custom summary from frontmatter
  2. First 160 characters of post content (auto-generated)

Frontmatter:

---
title: "My Post"
summary: "A brief summary of this post"
---

For SitePage

{{#if page.summary}}
<p class="page-summary">{{page.summary}}</p>
{{/if}}

Priority:

  1. metadata["summary"] - Custom summary from frontmatter
  2. null if not set

Description

The description property is used for SEO meta descriptions and falls back to summary.

For BlogPost

{{! Description from metadata, or summary, or first 160 chars of content }}
<meta name="description" content="{{post.description}}">

Priority:

  1. metadata["description"] - Custom description for SEO from frontmatter
  2. metadata["summary"] - Falls back to summary
  3. First 160 characters of post content (auto-generated)

Frontmatter:

---
title: "My Post"
summary: "A brief summary for listings"
description: "A different description optimized for search engines"
---

For SitePage

{{! Description from metadata, or summary }}
{{#if page.description}}
<meta name="description" content="{{page.description}}">
{{/if}}

Priority:

  1. metadata["description"] - Custom description for SEO from frontmatter
  2. metadata["summary"] - Falls back to summary
  3. null if neither is set

Example: Complete Post Card

<article class="post-card">
  <h2><a href="{{post.path}}">{{post.title}}</a></h2>

  {{#if post.summary}}
  <p class="summary">{{post.summary}}</p>
  {{/if}}

  <div class="meta">
    <time>{{post.date}}</time>

    {{#if post.tags}}
    <div class="tags">
      {{#each post.tags}}
      <span class="tag">{{this}}</span>
      {{/each}}
    </div>
    {{/if}}
  </div>
</article>

Direct Metadata Access

You can still access raw metadata values directly:

{{! Access raw metadata string }}
{{post.metadata.tags}}  <!-- "kotlin, web, tutorial" -->

{{! Access parsed list }}
{{#each post.tags}}{{this}}{{/each}}  <!-- kotlin web tutorial -->

However, it's recommended to use the convenience properties (tags, description, summary) instead of accessing metadata directly.

, metadata={title=Metadata Properties, layout=default}, source=DatasourceItemSource(type=api, id=api-metadata-properties, path=/api/metadata-properties/, title=Metadata Properties))

Tips

With a configured config.json, the rest of Statik (content folders, templates, and assets) falls naturally into place.