Skip to content


In Kirby, pages are represented by folders in /content. For each page, there is a separate folder that contains the corresponding text and media files.


Pages can have 3 states:

  • draft
  • listed and
  • unlisted.

Pages can be created directly in the file system, via the Panel or programmatically. If you create a new page via the Panel, it is always created as a draft. In the file system, you are free to create either drafts or listed/unlisted pages directly.

Creating pages manually in the content folder

Pages are stored as subfolders of the /content folder. To create a new page manually, create a new folder and add a text file with the extension .txt (default) or .md (optional configuration setting).

A simple folder structure could look like this:

  • /content
    • /home
      • home.txt
    • /projects
      • project.txt
    • /blog
      • blog.txt
    • /contact
      • contact.txt

The name of this file defines which template is used to render the content.

Content filename Template filename
home.txt home.php
projects.txt projects.php
contact.txt contact.php

Each page folder is accessible via its URL, e.g. you can access the projects folder by entering your domain name followed by the UID of the folder into your browser's address bar: If your projects folder contains subpages, the subpage project-a would therefore be accessible via etc.

URLs can be modified via Kirby's router.

Creating page sections that allow adding pages

Before a user can add new pages via the Panel, you have to set up a pages section that has either the status draft or the status all.

Creating Drafts

Drafts are stored in a _drafts subfolder for every page. These drafts are not accessible when you are not logged in. Every new page in the Panel is created as a draft first. This prevents accidental publishing of a page that is not ready yet.

How to create a draft

In the Panel

Click on the "Add" button in the top right corner of a list of pages. Every new page is automatically added as a draft.

In the content folder

If you want to create a draft manually in the content folder you can create a _drafts subfolder in the parent page folder (if it's not there yet) and inside create your draft page folder.

  • /content/projects/_drafts/my-project-draft

How to publish a draft

In the Panel

To publish a draft in the Panel, click on the "Draft" button with the red status icon in the toolbar or go to "Settings" > "Change status".

Validation errors

To publish a draft in the Panel, all required fields must be filled in and all validations must pass. Otherwise publishing the draft will fail.

In the content folder

To publish a draft manually in your content folder, drag it from the _drafts folder to the parent directory:


  • /content/projects/_drafts/my-project-draft


  • /content/projects/my-project-draft

You can apply additional sorting by prepending a number if wanted. Delete the _drafts folder if it's no longer needed. Otherwise there's no harm in just leaving it there.

Drafts in your templates

Drafts are not included in $page->children() collections. If you have to access them in your templates, you can use the $page->drafts() method.

Listed pages

Listed pages are public pages with a sorting number in your content folder.

Manual sorting

For a normal menu, a list of projects or any other non-alphabetical list you often need manual sorting. This is done by prepending a number followed by an underscore:

  • 1_best-project
  • 2_okayish-project
  • 3_dont-look-at-this-one

Date-based sorting

For blogs, events or anything else that is date-based, the date can be prepended as the sorting number, also followed by an underscore:

  • 20121212_hello-world
  • 20181212_really-bad-at-regular-blogging

Alphabetical sorting

To sort pages alphabetically, 0 is prepended as the sorting number in the file system:

  • 0_alpaca
  • 0_bear
  • 0_camel

Unlisted pages

Pages without a sorting number are unlisted pages. Unlisted pages are still accessible by anyone who knows the URL to the page. Unlisted pages are useful if you want to exclude them from menus or any kind of list. A typical example for an unlisted page would be the error page or maybe a new project that still needs to be reviewed by the client via URL, but not yet listed.

  • im-only-accessible-via-url

Creating pages programmatically

Pages can also be created via Kirby's API methods in a controller, template, plugin, hook etc. This is useful if you want to create pages from form data, external files (like an Excel or CSV file), or from an external API.

The basic syntax for creating a page with code looks like this:


$content = [
  'title' => 'An interesting title',
  'text'  => 'Some great content here…'

  'content'  => $content,
  'slug'     => 'test-article',
  'template' => 'article'

The above code only works if you are logged in, because it respects the permissions of the currently logged in user. Learn more about permissions and impersonatig users.