A Page represents a single content document within your project. You can think of each page as a single resource and should group related content, or content likely to be read together into pages.
Each page:
-
Lives within a directory
-
Contains sections that hold the actual content
-
Has permissions controlling who can access and modify it
type Page { id: ID! # Unique identifier slug: String! # URL-friendly identifier directory: String! # Directory path (e.g., "docs/api") title: String # Optional display title author: User # User who created the page sections: [Section!]! # Content sections permissions: PagePermissions! # Access controls}Pages can be referenced in two different ways: by its id or by a slug.
-
Page IDs: are randomly generated, immutable strings, generated by our API. This means once a page has been created it won't ever be changed and is particularly great for hardcoding links between pages.
-
Slugs: are human-readable, URL-safe identifiers that you define to name pages and express site structure. They are stable for linking and navigation, but can be updated when your content or structure evolves.
Pages have some data that is updated automatically:
- Directory: page
directoryis auto-generated based on the page's slug and will be used to co-locate similar pages. For example, a page could be stored at/docs/pagesand another page at/docs/users, both have the directory/docs. More about directories below. - Author: Authors are the simplest to understand permission boundary between a page and a user. We'll discus more about permissions later, but for now just know that the user that creates a page is stored as the author. If a user isn't known (for example if the page is created automatically by a system process, or if an unauthenticated user creates a page) then a pages
authorwill be null.
A Directory represents a folder-like node in your project’s content tree. It groups related pages under a shared path (for example docs/api) and can also contain nested subdirectories, letting you model your site structure in a familiar, hierarchical way.
Directories are useful for:
-
Organising content: keep pages that belong together (like all API docs) under the same directory.
-
Building navigation: use a directory’s children to render a sidebar or tree view (directories and pages).
-
Querying by location: fetch all pages in a directory (pages) or traverse the hierarchy (children) starting from any directory path.
-
Permissions by structure: apply and enforce access controls at the directory level (via permissions) to manage who can view or edit content within a section of the tree.
In practice, if you create pages with slugs like /docs/users and /docs/pages, they’ll naturally live under the docs directory, and docs can have its own children (subdirectories and pages) to represent your documentation structure.
type Directory implements PageReference { id: ID! # Unique database identifier slug: String! # URL-friendly identifier for the directory path: String! # Full path from root to this directory pages: [Page!]! # Pages directly contained in this directory children: DirectoryConnection! # Child directories and pages contained within this directory permissions: PagePermissions!}Sections are the logical grouping within a page. They can be used to:
-
Store rich text
-
Store media content such as images and videos
-
Nest and group other sections
interface Section { id: ID! # Unique identifier for the section slug: String! # URL-friendly slug for the section}Text sections are the simplest form of Section. They haver a field markdown that you can store string data in and an auto-generated plaintext field that returns the contents of markdown with any markdown formatting removed.
type TextSection implements Section { id: ID! # Unique identifier for the section slug: String! # URL-friendly slug for the section markdown: Markdown! # Rich markdown content of the section plaintext: String! # Auto-generated plain text version of the content}Group sections allow you to structure and group other sections into more meaningful data structures.
type GroupSection implements Section { id: ID! # Unique identifier for the section slug: String! # URL-friendly slug for the section children: [Section!]! # All child sections contained in this group}