Pages
Pages are Markdown files that become HTML pages on your site.
Basic Structure
+++
title = "My Page"
date = "2024-01-15"
+++
Your content in **Markdown**.
The +++ block is TOML front matter. Content below becomes HTML.
Front Matter
Required
| Field | Type | Description |
|---|---|---|
| title | string | Page title |
Common Fields
| Field | Type | Default | Description |
|---|---|---|---|
| date | string | — | Publication date (YYYY-MM-DD) |
| description | string | — | SEO description |
| draft | bool | false | Exclude from production builds |
| template | string | "page" | Template to use |
| weight | int | 0 | Sort order (lower = first) |
| image | string | — | Featured image for social sharing |
| tags | array | [] | Tag taxonomy terms |
| categories | array | [] | Category taxonomy terms |
All Fields
| Field | Type | Description |
|---|---|---|
| updated | string | Last updated date |
| slug | string | Custom URL slug |
| path | string | Custom URL path |
| aliases | array | Redirect URLs to this page |
| authors | array | Author names |
| toc | bool | Show table of contents |
| in_search_index | bool | Include in search |
| in_sitemap | bool | Include in sitemap |
| insert_anchor_links | bool | Add heading anchors |
| redirect_to | string | Redirect page to this URL |
| render | bool | Render page to output (default: true) |
| extra | table | Custom metadata |
Examples
Blog Post
+++
title = "Getting Started with Crystal"
date = "2024-01-15"
description = "Learn Crystal programming basics"
tags = ["crystal", "tutorial"]
authors = ["Alice Smith"]
image = "/images/crystal-guide.png"
+++
Crystal is a fast, compiled language...
Draft
+++
title = "Work in Progress"
draft = true
+++
Not visible in production.
Build with drafts: hwaro build --drafts
Custom Template
+++
title = "Landing Page"
template = "landing"
+++
Uses `templates/landing.html` instead of `page.html`.
Weighted Order
+++
title = "Introduction"
weight = 1
+++
+++
title = "Getting Started"
weight = 2
+++
Lower weight appears first.
URL Aliases
+++
title = "New Page"
aliases = ["/old-url/", "/another-old-url/"]
+++
Redirects from old URLs to this page.
Custom Metadata
+++
title = "Product Review"
[extra]
rating = 4.5
featured = true
pros = ["Fast", "Reliable"]
+++
Access in templates: {{ page.extra.rating }}
Content Summary
Use <!-- more --> to define a summary:
+++
title = "Long Article"
+++
This is the summary shown in listings.
<!-- more -->
The full article continues here...
Markdown Syntax
Text
**bold** and *italic*
`inline code`
[link](https://example.com)

Lists
- Unordered
- Items
1. Ordered
2. Items
Code Blocks
```javascript
console.log("Hello");
```
Tables
<table>
<thead>
<tr>
<th>Header</th>
<th>Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cell</td>
<td>Cell</td>
</tr>
</tbody>
</table>
Table cells support inline Markdown: bold, italic, code spans, links, , and ~~strikethrough~~.
<table>
<thead>
<tr>
<th>Feature</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>Bold</td>
<td><strong>important</strong></td>
</tr>
<tr>
<td>Italic</td>
<td><em>emphasis</em></td>
</tr>
<tr>
<td>Code</td>
<td><code>config.toml</code></td>
</tr>
<tr>
<td>Link</td>
<td><a href="https://example.com">Hwaro</a></td>
</tr>
<tr>
<td>Image</td>
<td><img src="/img/logo.png" alt="logo"></td>
</tr>
<tr>
<td>Strikethrough</td>
<td><del>deprecated</del></td>
</tr>
</tbody>
</table>
Internal Links
Use @/ to link to other content pages by their source path. Hwaro resolves these to the correct output URL at build time.
[Read the post](@/blog/my-post.md)
[About section](@/about/_index.md)
[With anchor](@/blog/my-post.md#introduction)
This is useful because you don't need to know the final URL — Hwaro calculates it from the content path. If the target page doesn't exist, the link is left unchanged and a warning is logged during build.
| Syntax | Resolved URL |
|---|---|
@/blog/post.md |
/blog/post/ |
@/blog/_index.md |
/blog/ |
@/blog/post.md#section |
/blog/post/#section |
Blockquotes
> Quote text
Asset Colocation
You can keep related assets (images, PDFs, etc.) in the same directory as your content file. This is known as a Page Bundle.
To use this feature, rename your markdown file to index.md (for regular pages) or _index.md (for section pages) and place it in a directory named after your page.
Example Structure:
content/
└── blog/
├── my-trip/
│ ├── index.md <-- The page content
│ ├── photo.jpg <-- Asset
│ └── data.json <-- Asset
└── _index.md
Hwaro will copy all non-markdown files from the page bundle directory to the output directory, maintaining the relative path.
In your markdown, you can link to these assets using relative paths:

[Download Data](data.json)
Accessing Assets in Templates
You can access the list of colocated assets in your templates using page.assets. This returns an array of relative paths to the files.
{% for asset in page.assets %}
{% if asset is matching("[.](jpg|png)$") %}
<img src="{{ get_url(path=asset) }}" alt="Gallery Image">
{% endif %}
{% endfor %}
URL Mapping
| File | URL |
|---|---|
| content/index.md | / |
| content/about.md | /about/ |
| content/blog/post.md | /blog/post/ |
See Also
- Sections — Group related pages
- Data Model — Page properties in templates