# Article Sections

> Split a site into sections, each with its own tab and navigation.

A section is a part of the site, such as a guide and an API reference, with its own URL prefix, its own tab and its own navigation: while one of its pages is open, the sidebar and the previous and next links show only that section's pages. Htmlpress ships four section types:

- **Article**: the default. The pages under a prefix, grouped in the sidebar by folder.
- **Custom**: just a tab, leading to a URL.
- **Blog**: dated posts, newest first, with tag pages and an RSS feed.
- **Changelog**: one page per version of a Markdown changelog.

## Basic usage

```yaml
site: https://example.com
sections:
  - title: Guide
    prefix: /
  - title: API
    prefix: /api/
    siteTitle: API Reference
  - title: GitHub
    type: custom
    url: https://github.com/datisthq/htmlpress
```

When `sections` is omitted, every page renders into a single navigation, which suits small sites.

## Common fields

Every section accepts:

| Field             | Default                        | Purpose                                                                                                                                                                  |
| ----------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `title`           | none, required                 | The tab's name, and the section's group in `llms.txt`.                                                                                                                   |
| `type`            | `article`                      | `article` owns pages; `custom` is just a tab to its `url`.                                                                                                               |
| `prefix`          | none, required for `article`   | The folder path its pages share, starting and ending with `/` (`/`, `/api/`). The tab leads to the page at the prefix, else the section's first page.                    |
| `url`             | none, required for `custom`    | Where a `custom` tab leads.                                                                                                                                              |
| `position`        | `header`                       | `header` for a tab beside the header links, `sidebar` for an entry in the section picker above the sidebar's pages. On a phone the picker lists every section.           |
| `icon`            | none                           | A [built-in icon](/authoring/rich-elements/#icons) before the title, such as `book-open`.                                                                                |
| `siteTitle`       | the site's `title`             | The brand's title while one of the section's pages is open.                                                                                                              |
| `siteLink`        | `/`                            | Where the brand links while one of the section's pages is open.                                                                                                          |
| `siteDescription` | the site's `description`       | The description for the section's pages without one of their own, and under the brand.                                                                                   |
| `source`          | none, required for `changelog` | The Markdown changelog to split, relative to the project; it must stay inside the project and not be a dot-file. Or a GitHub repository URL, to build from its releases. |
| `version`         | `false`                        | For a `changelog`: show the latest version beside the title.                                                                                                             |

Any other field is an error, and so is an `article` section without a `prefix`, a prefix that does not start and end with `/`, or a `custom` section without a `url`. On a phone every section, header or sidebar, is listed in the sidebar.

## Article sections

Plain docs, and the default: you can omit `type` entirely.

```yaml
- title: Guide
  prefix: /guide/
```

Inside a section, the sidebar nests its pages by folder, at any depth. Pages at the root come ungrouped, and each folder gets its own collapsible group inside its parent's, named by the title of its `index.html`, else the folder's name:

- introduction.html

- guides

  - index.html
  - install.html
  - deploy.html

- reference

  - index.html

  - cli.html

  - api

    - index.html
    - auth.html

`guides/index.html` is served at `/guides/`, the group's own page, and also names the folder in the breadcrumbs. Without `sections`, the whole site is grouped this way.

A `custom` section owns no pages. Its tab is marked current when its `url` is internal and points at the open page or a folder above it (`/` only on the home page); an external URL never is.

```yaml
- title: Blog
  type: custom
  url: https://blog.example.com
```

## Blog sections

A `blog` section's pages are posts: dated by `<meta name="date">`, signed by `<meta name="author">` and tagged by `<meta name="keywords">`. The previous and next links list them newest first. The sidebar links to all posts, the five newest, the RSS feed (with `site`) and every tag; a changelog's sidebar likewise links to all releases and the five newest. The build adds:

- an index at the prefix listing every post, dated by the newest, unless the section has its own `index.html`; the posts page from one to the next, the index stays out of the previous and next links;
- a page per tag at `tags/<tag>/` under the prefix;
- an RSS feed at `rss.xml` under the prefix, linked from every page's head, when `site` is set, since a feed links absolutely.

```yaml
- title: Blog
  type: blog
  prefix: /blog/
```

## Changelog sections

A `changelog` section splits its `source` at each `##` heading into a page per version at `<version>/` under the prefix, newest first as the file lists them, plus an index listing them, each version a heading of the page's table of contents. A release-please heading, `## [0.2.0](…) (2026-10-01)`, gives the version and its date; the release's `###` headings become its sections. With `version: true` the tab shows the latest version.

```yaml
- title: Changelog
  type: changelog
  prefix: /changelog/
  source: CHANGELOG.md
  version: true
```

A `source` naming a GitHub repository, `https://github.com/acme/tool`, builds a page per release instead: its tag as the version, its publish date and notes, and a "View on GitHub" link. Raw HTML in the notes shows as text, so a release cannot add scripts to the site. The build reads the first 100 releases from the GitHub API, with `GITHUB_TOKEN` from the environment when set, and caches them in `.htmlpress/cache/`; a later build revalidates the cache and falls back to it when GitHub cannot be reached. Without a cache, a failed request fails the build.

## Ordering and matching

Page URLs are matched to sections by longest prefix wins. Given `/api/v2/auth/` and sections with prefixes `/` and `/api/`, the page is placed in `/api/`. Because a prefix is a folder path, `/guide/` never takes `/guides/`. Pages no section owns form one more part of their own, with its own navigation.

`llms.txt` groups its links by section too, in the config's order, with the pages no section owns last under "Other"; without `sections`, by top folder.

Within a navigation, a page belongs to the group of its folder's `index.html`, and that index to its parent folder's: `guides/cli/run.html` sits in the `cli` group inside "Guides". A folder without an `index.html` makes no group, and its pages sit at the top. Pages sort by `<meta name="order">` among their siblings: the root `index.html` always leads, orders of 0 or more follow ascending, then the unordered pages by path, then negative orders, with `-1` last. A group sits where its `index.html` sorts, so give it an order to place the whole group. The pager walks the sidebar top to bottom, each group's index before its pages.

A `404.html` at the root is left out of the sidebar; it is the page a host shows for a missing URL, and a project without one gets a built-in "Page not found".

## See also

- [External Links](/customization/external-links/): add links next to your section tabs.
- [Frontmatter](/authoring/frontmatter/): the `<title>` and `<meta name="order">` that drive section content.
