Bolt CMS Docs
Sign in

Architecture

Page types

Bolt has exactly two page types — PHP and Markdown. The framework tells them apart by file extension alone; everything else is convention.

Two page types

A page in Bolt is just a file inside the pages/ directory, and the framework cares about exactly one thing when it loads that file: the file extension. There are only two page types.

Extension How content is produced Best for
.php The file is executed. It sets $page['config'] and builds $page['content'] itself. Anything dynamic — logic, loops, includes, forms, bespoke markup.
.md Frontmatter becomes $page['config']; the body is rendered to HTML by Parsedown into $page['content']. Static prose — guides, articles, simple content pages.

That is the whole type system — the extension decides how a page's content is produced. How a page looks is a separate concern, set by the layout it selects rather than by its type. The same two file types can produce a landing page, an article, or a docs page.

Whichever type a page is, it ends up as the same $page structure and flows through the same render pipeline: a header, a layout, and a footer, each chosen by a key in $page['config'].

How Bolt picks a file

Bolt uses file-based routing — the URL path maps straight to a file under pages/, with no route table to register. For a given path, it checks four candidates and the first match wins:

GET /pricing

1. pages/pricing.php         ← PHP file
2. pages/pricing/index.php   ← PHP page with its own resources
3. pages/pricing.md          ← Markdown file
4. pages/pricing/index.md    ← Markdown page with its own resources

Two consequences fall out of this order:

  • PHP wins ties. If both pricing.php and pricing.md exist, the PHP file is served. A Markdown page is used only when no PHP file resolves to the same URL.
  • The index forms are for pages with their own resources. Reach for pricing/index.php (or pricing/index.md) when a page ships files of its own — images, scripts, .css, a .pdf to link to, and so on. Its own folder keeps those assets beside it, addressable with relative paths; a page with no extra files is simpler as a single pricing.php or pricing.md. This very page is organized as a folder for exactly that reason.

The home page (/) is resolved the same way, against pages/index.php then pages/index.md. For the full URL-sanitization rules, see Routing.

PHP pages

A PHP page owns the entire request. It runs whatever code it needs, then hands two things back to the renderer: a $page['config'] array and a $page['content'] string. The idiomatic pattern is to capture markup with output buffering:

<?php

$page['config']['title']  = 'Contact - Acme Club';
$page['config']['layout'] = 'canvas';        // optional — defaults to "default"

ob_start();
?>

<section class="py-20">
    <h1>Get in touch</h1>
    <p>We'd love to hear from you.</p>
</section>

<?php
$page['content'] = ob_get_clean();
?>

Because the file is plain PHP, a page can do anything PHP can: query a data store, loop over records, branch on the URL, post a form, or pull in shared partials with include (a pricing grid, a CTA, a callout). The ob_start() / ob_get_clean() pair simply collects everything echoed in between into $page['content']; the layout you selected then wraps it.

Configuration keys

Set these on $page['config']. Each maps a name to a file in the matching top-level directory, so the values are file names without the .php extension.

Key Purpose Default
title Text for the document <title> The request host
header Which file in headers/ to render default
layout Which file in layouts/ wraps the content default
footer Which file in footers/ to render default

A page may also set any custom key it likes (an article date, an author, a feature flag) for its layout to consume — the config array is just a bag of values passed through to the templates.

Markdown pages

A Markdown page carries no logic. It is frontmatter plus prose: Bolt reads the frontmatter into $page['config'], renders the body to HTML with Parsedown, and stores the result as $page['content']. It is the fastest way to add a route.

Title: Hello, Bolt
Layout: canvas
Author: Matt Todaro

---

## Welcome

This page is written in **Markdown**. Parsedown renders the body
to HTML and drops it into the layout named in the frontmatter.

- Bullet lists work
- So does `inline code`
Bolt's frontmatter is not fenced. Unlike Jekyll or YAML front matter, you do not wrap it in a leading ---. The Key: Value lines come first, and a single --- closes the block. Start the file with --- and Bolt will treat your frontmatter as body text instead.

Frontmatter rules

  • One Key: Value per line, before the first ---. Everything after that --- is the page body.
  • Keys are normalized — lowercased, with spaces turned into underscores. Author URL becomes author_url.
  • Values keep their colons, so Author URL: https://example.com is parsed correctly.
  • Frontmatter is required. A Markdown file with no --- anywhere returns a 404.

What a Markdown page cannot do is run code, branch, or include a partial. It picks its appearance with the Layout key and otherwise just supplies content. The moment you need any of that, reach for a PHP page.

Choosing between PHP and Markdown

  • Reach for Markdown when a page is mostly text and needs no logic — it is quicker to write and impossible to break with a stray bug.
  • Reach for PHP when you need data, conditionals, forms, shared includes, or hand-built markup.
  • You can mix both freely in one site. Since both produce the same $page shape, switching a page's type later never changes its URL — and because PHP wins resolution, adding a .php file beside an existing .md page takes over immediately, so delete the now-unused .md.

Appearance is set by the layout

Page type governs how content is produced; how that content looks is a separate choice, made with the layout key. The same two file types drive every page on a site, each selecting the layout that fits:

  • A landing or product page is typically a .php file on the canvas layout, arranging full-width sections and a hero.
  • An article is any page — PHP or Markdown — with Layout set to article.
  • A docs page uses an article-style layout with navigation around it.

Choose a page's look with the layout key and the files in your site's layouts/ directory — see Layouts & templates for what each one provides.

Layouts & templates Markdown example