# Pages

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

```graphql title="Page Data Structure"
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
}
```


### Page IDs

Pages can be referenced in two different ways: by its `id` or by a `slug`.&#x20;

* **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:&#x20;**&#x61;re 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.


### Page Metadata

Pages have some data that is updated automatically:

* **Directory:** page `directory` is 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/pages` and 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 `author` will be null.


## Directories

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.

```graphql
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

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

```graphql title="Section Data Structure"
interface Section {
  id: ID!       # Unique identifier for the section
  slug: String! # URL-friendly slug for the section
}
```


### Text Sections

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.

```graphql title="TextSection Data Structure"
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

Group sections allow you to structure and group other sections into more meaningful data structures.

```graphql
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
}
```

