Content Organization
How the filesystem maps to your site structure
sukr builds your site structure from your content/ directory. No routing config needed — the filesystem is the config.
The Rule¶
content/foo/bar.md → public/foo/bar.html
content/about.md → public/about.html
content/_index.md → public/index.html
That's it. Paths mirror exactly, with .md becoming .html.
Directory Layout¶
content/
├── _index.md # Homepage (required)
├── _404.md # → /404.html (custom error page, optional)
├── about.md # → /about.html
├── contact.md # → /contact.html
├── blog/ # Section directory
│ ├── _index.md # → /blog/index.html (section index)
│ ├── first-post.md # → /blog/first-post.html
│ └── second-post.md # → /blog/second-post.html
└── projects/
├── _index.md # → /projects/index.html
└── my-app.md # → /projects/my-app.html
What Makes a Section¶
A section is any directory containing _index.md. This file:
- Provides metadata for the section (title, description)
- Triggers section listing behavior
- Appears in the navigation
Directories without _index.md are ignored.
Custom 404 Page¶
To add a custom "not found" page, create content/_404.md:
+++
title = "Page Not Found"
+++
# Page Not Found
The page you're looking for doesn't exist or has been moved.
[Return to the homepage](/)
sukr renders this to 404.html in the output root. The file is optional — if you don't create _404.md, no 404 page is generated.
Most static hosts (Cloudflare Pages, Netlify, GitHub Pages, Vercel) automatically serve /404.html when a visitor hits an unmatched route. No host-side configuration is needed beyond having the file present.
Draft Mode¶
Set draft = true in frontmatter to exclude content from the build:
+++
title = "Work in Progress"
draft = true
+++
Drafts are filtered from all output — page rendering, navigation, section listings, feeds, and the sitemap. The file stays in your content directory but produces no HTML. Remove the field (or set draft = false) to publish.
Aliases (Redirects)¶
Aliases let you redirect old URLs to a page's current location. Set aliases in frontmatter:
+++
title = "New Location"
aliases = ["/old/path", "/another/old/path"]
+++
For each alias, sukr generates an HTML redirect stub using <meta http-equiv="refresh">. Bare paths like /old/path produce /old/path/index.html; paths with extensions like /old/page.html are used as-is.
Section Discovery¶
sukr automatically discovers sections during the build:
- Scans
content/for directories containing_index.md - Collects all
.mdfiles in that directory (excluding_index.md) - Renders the section index template with the collected items
- Renders individual content pages (for blog-type sections)
The section type determines which template renders the index. It resolves in order:
- Frontmatter override —
section_type = "blog"in the section's_index.md - Directory name —
content/blog/becomes typeblog
For the full section type reference (built-in types, frontmatter fields, and template dispatch), see Sections.
Navigation Generation¶
Navigation builds automatically from:
- Top-level
.mdfiles (except_index.md) → page links - Directories with
_index.md→ section links
Items sort by weight in frontmatter (lower first), then alphabetically.
+++
title = "Blog"
weight = 10 # Appears before items with weight > 10
+++
Hierarchical Navigation¶
When nav.nested = true in your config, section children appear as nested sub-items:
Features ← Section link
├─ Templates ← Child page
├─ Sections ← Child page
└─ Highlighting ← Child page
Getting Started ← Top-level page
Child pages inherit their parent section's position in the nav tree. Within a section, children sort by weight then alphabetically.
Without nested navigation (the default), only top-level items appear in the nav.
URL Examples¶
| Source Path | Output Path | URL |
content/_index.md |
public/index.html |
/ |
content/_404.md |
public/404.html |
/404.html |
content/about.md |
public/about.html |
/about.html |
content/blog/_index.md |
public/blog/index.html |
/blog/ |
content/blog/hello.md |
public/blog/hello.html |
/blog/hello.html |
Key Points¶
- No config files for routing
- Directory names become URL segments
_index.md= section index, not a regular page_404.md= custom error page, rendered to404.htmlat output root- Flat output structure (no nested
index.htmlper page)