Skip to content

Project Structure

Understand Balzac’s directory structure and default configuration.

A typical Balzac project looks like this:

my-site/
├── balzac.toml # Configuration file
├── dist/ # Generated output (created by balzac)
├── pages/ # Handlebars templates for pages
│ ├── index.hbs
│ └── posts/
│ └── details.hbs
├── partials/ # Handlebars partials (optional)
│ └── header.hbs
├── layouts/ # Handlebars layouts (optional)
│ └── main.hbs
├── assets/ # Static files (optional)
│ ├── style.css
│ └── logo.svg
└── content/ # Markdown content (optional)
└── posts/
├── first-post.md
└── second-post.md

The only required directory. Contains Handlebars templates that become your static pages.

pages/index.hbs:

<!DOCTYPE html>
<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>

Output: dist/index.html

Created automatically by Balzac. Contains the generated static site. Do not manually edit this directory.

Store markdown content for collections. Each subdirectory becomes a collection.

content/
├── posts/
│ ├── hello-world.md
│ └── about-me.md
└── docs/
├── getting-started.md
└── advanced-topics.md

Each markdown file needs a corresponding template in pages/<collection>/details.hbs.

Reusable template snippets that can be included in other templates.

partials/header.hbs:

<header>
<h1>{{site_name}}</h1>
</header>

Use in templates:

{{> header}}

Reusable page layouts that wrap content.

layouts/main.hbs:

<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
{{> header}}
{{{body}}}
{{> footer}}
</body>
</html>

Static files copied directly to the output directory.

assets/
├── style.css → dist/assets/style.css
├── logo.svg → dist/assets/logo.svg
└── favicon.ico → dist/assets/favicon.ico

Access in HTML:

<link rel="stylesheet" href="/assets/style.css">

The main configuration file in your project root.

[global]
site_name = "My Site"
[hooks]
build_before = "pnpm build"
[bundler.vite]
enabled = true
manifest_path = "dist/.vite/manifest.json"

See Configuration Reference for all options.

Handlebars files in pages/:

  • index.hbsdist/index.html
  • about.hbsdist/about.html
  • contact.hbsdist/contact.html

Markdown files in content/<collection>/:

  • content/posts/hello-world.mddist/posts/hello-world.html
  • content/posts/my-first-post.mddist/posts/my-first-post.html

Collection templates must be named details.hbs:

  • pages/posts/details.hbs - Template for the posts collection
  • pages/docs/details.hbs - Template for the docs collection

You can customize directory names in balzac.toml:

output_directory = "./build"
pages_directory = "./templates"
layouts_directory = "./src/layouts"
partials_directory = "./src/partials"
assets_directory = "./static"
content_directory = "./markdown"

The smallest possible Balzac project:

minimal/
├── balzac.toml
└── pages/
└── index.hbs

balzac.toml:

# Empty configuration uses all defaults

pages/index.hbs:

<h1>Hello, World!</h1>
blog/
├── balzac.toml
├── pages/
│ ├── index.hbs # Home page with post list
│ ├── about.hbs # About page
│ └── posts/
│ └── details.hbs # Individual post template
├── partials/
│ ├── header.hbs
│ ├── footer.hbs
│ └── post-card.hbs
├── layouts/
│ └── default.hbs
├── assets/
│ ├── style.css
│ └── logo.svg
└── content/
└── posts/
├── first-post.md
└── second-post.md
docs/
├── balzac.toml
├── pages/
│ ├── index.hbs # Landing page
│ └── docs/
│ └── details.hbs # Doc page template
├── partials/
│ ├── sidebar.hbs
│ ├── header.hbs
│ └── footer.hbs
├── assets/
│ ├── theme.css
│ └── logo.svg
└── content/
└── docs/
├── getting-started.md
├── installation.md
└── configuration.md
  1. Organize by purpose - Group files logically (pages, assets, content)
  2. Use consistent naming - lowercase with hyphens for files
  3. Keep it simple - Start with minimal structure, add as needed
  4. Separate concerns - Templates in pages/, content in content/, assets in assets/
  5. Use partials - Reuse common elements (header, footer, navigation)