Loading Editor...
h3
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
The Sections API enables flexible content modeling within pages through a hierarchical section system. Sections represent discrete content blocks: text, or groups containing other sections.
Sections are the building blocks of page content, implementing a common interface while supporting multiple content types. There are two section types: TextSection, which holds Markdown, and GroupSection, which holds other sections. Images go inside text sections, as Markdown images. Pages introduces sections, and the Page Editor is where you write them.
Every kind of section shares the Section interface, so a query can select id and slug on any section without knowing its type. Use ... on TextSection or ... on GroupSection to select the fields only one type has.
interface Section { id: ID! slug: String! name: String!}A TextSection holds one block of content written in Markdown: headings, paragraphs, lists, links, code and images. It is the section you will use most, and what the editor calls a text section: see Text sections and Markdown. Alongside the Markdown, plaintext gives the same content with the formatting removed, ready for search indexes, previews and meta descriptions.
type TextSection implements Section { id: ID! slug: String! name: String! markdown: Markdown! plaintext: String!}
Fields:
markdown (Markdown!) - Rich markdown content of the sectionplaintext (String!) - Plain text version auto-generated from markdownA GroupSection holds other sections, so you can give a page structure: the steps of a tutorial, the questions in an FAQ, or the cards in a feature grid. Groups can hold other groups.
type GroupSection implements Section { id: ID! slug: String! name: String! children: [Section!]! child(section: SlugOrId!): Section}
Fields:
children ([Section!]!) - All child sections contained in this groupchild(section: SlugOrId!) - Find a specific child section by slug or IDAdd a section to a page with addSection. Without parent it goes at the top level of the page; with one, it goes inside that group. Without position it goes at the end, and a position counts from 0 among its new siblings. If you give it no slug, one is generated for you, so give it one if you want readable anchors and references.
mutation AddSection( $page: SlugOrId! $section: SectionInput! $parent: SlugOrId $position: Int) { addSection( page: $page section: $section parent: $parent position: $position ) { id slug name ... on TextSection { markdown plaintext } ... on GroupSection { children { id slug name } } }}
Parameters:
page - Target page to add the section tosection - Section configuration (see SectionInput)parent - Optional parent section for nested placementposition - Optional zero-based index positionChange a section's content, its slug, or both, with editSection. Name the section with ref, by slug or ID. Edits are partial: only the fields you send change, and anything you leave out keeps its current value. An edit to a published page is live straight away.
mutation EditSection( $page: SlugOrId! $ref: SlugOrId! $section: SectionInput!) { editSection(page: $page, ref: $ref, section: $section) { id slug name ... on TextSection { markdown plaintext } }}
Parameters:
page - The page containing the section (slug or ID)ref - The section to edit — accepts either a slug ({ slug: "introduction" }) or a section ID ({ id: "sct_..." })section - Fields to update; unset fields are preservedRemove a section from a page with removeSection, by its slug or ID. It returns the page, so you can select the remaining sections to refresh what you are showing.
mutation RemoveSection($page: SlugOrId!, $ref: SlugOrId!) { removeSection(page: $page, ref: $ref) { id slug children { id slug name } }}Reorder a page's sections, or move one into or out of a group, with moveSection. to.index counts from 0 among the destination's sections, and to.parent names the group to move into. Leave parent out to move the section to the top level of the page. It returns the page, with its sections in their new order.
mutation MoveSection( $page: SlugOrId! $ref: SlugOrId! $to: PageMoveDestination!) { moveSection(page: $page, ref: $ref, to: $to) { id slug children { id slug name } }}addSection and editSection take a SectionInput, which says which kind of section you mean by which field you set. Set exactly one: text for a text section, or group for a group.
input SectionInput { group: GroupSectionInput text: TextSectionInput}
Note: Only one field should be specified per section.
Describes a text section's slug and Markdown content. Both fields are optional. When adding a section, a missing slug is generated for you. When editing, a field you leave out keeps its current value rather than being cleared.
input TextSectionInput { slug: String markdown: Markdown}
Fields:
slug - New slug for the section. Omit to keep the existing slug.markdown - New markdown content. Omit to keep the existing content.Describes a group section: its slug, and the sections to create inside it. Pass children to build a group and its contents in a single request.
input GroupSectionInput { slug: String children: [SectionInput!]}Tells moveSection where a section should end up: which group, and what position within it.
input PageMoveDestination { parent: SlugOrId index: Int!}
Fields:
parent - Parent section to move under (null for root level)index - Zero-based position within the parentFetch a page with all of its content in one GraphQL query, ready to render. children returns the top-level sections in order. For a group, select its children too, nesting one level for each level of grouping you use.
query GetPageWithSections($pageRef: SlugOrId!) { page(ref: $pageRef) { id slug title children { id slug name ... on TextSection { markdown plaintext } ... on GroupSection { children { id slug name ... on TextSection { markdown } } } } }}Fetch one section of a page by its slug or ID with section, for example to render a single block such as a hero banner or a footer note. It returns null if the page has no such section. Select the fields for each type you expect, since the section may be text or a group.
query GetSection($pageRef: SlugOrId!, $sectionRef: SlugOrId!) { page(ref: $pageRef) { section(ref: $sectionRef) { id slug name ... on TextSection { markdown plaintext } ... on GroupSection { children { id slug name } } } }}When you know the section you want is text, text saves you the type check: it returns a TextSection directly, so you can select markdown without ... on TextSection. It returns null if there is no section with that reference, or if the section is a group.
query GetTextSection($pageRef: SlugOrId!, $textRef: SlugOrId!) { page(ref: $pageRef) { text(ref: $textRef) { id slug name markdown plaintext } }}This example adds a text section with a heading and some bold text to the end of a page. The slug introduction gives it a readable anchor.
mutation { addSection( page: { slug: "my-page" } section: { text: { slug: "introduction" markdown: "# Introduction\n\nThis is the introduction section with **bold** text." } } ) { id slug ... on TextSection { markdown plaintext } }}This example builds a two-step tutorial in one request: a group section containing two text sections. Everything nested inside children is created with the group.
mutation { addSection( page: { slug: "my-page" } section: { group: { slug: "tutorial-steps" children: [ { text: { slug: "step-1" markdown: "## Step 1\n\nFirst, do this..." } } { text: { slug: "step-2" markdown: "## Step 2\n\nThen, do that..." } } ] } } ) { id slug ... on GroupSection { children { id slug name } } }}This example moves the introduction section into the tutorial-steps group, as its first section.
mutation { moveSection( page: { slug: "my-page" } ref: { slug: "introduction" } to: { parent: { slug: "tutorial-steps" } index: 0 } ) { id children { id slug name } }}Replace a text section's Markdown by sending only markdown. The slug stays as it is. The section can be named by slug, as in the first example, or by ID, as in the second. The Markdown you send replaces the section's whole content, so send the complete new version.
mutation { editSection( page: { slug: "my-page" } ref: { slug: "introduction" } section: { text: { markdown: "# Updated Introduction\n\nThis content has been updated with new information." } } ) { id slug ... on TextSection { markdown plaintext } }}
Reference by ID (slug or ID are both valid refs):
mutation { editSection( page: { slug: "my-page" } ref: { id: "sct_O1otxVDlcAIQvdCy" } section: { text: { markdown: "# Updated content" } } ) { id slug ... on TextSection { markdown } }}To rename a section, pass only slug. Its content stays as it is: a text section keeps its markdown, and a group keeps its children. The ref can be the section's slug or its ID, as in any edit.
Edit a text section's slug:
mutation { editSection( page: { slug: "my-page" } ref: { slug: "introduction" } section: { text: { slug: "new-introduction" } } ) { id slug }}
Edit a group section's slug:
mutation { editSection( page: { slug: "my-page" } ref: { slug: "tutorial-steps" } section: { group: { slug: "guide-steps" } } ) { id slug }}Sections support hierarchical organization through GroupSection containers:
When adding sections with a parent parameter, the section becomes a child of that parent GroupSection. The position parameter controls the order within the parent's children array.
A request that would go over a limit is refused.
| Limit | Value |
|---|---|
| Content of one section | 16 KB |
| Sections created by one mutation, nested ones included | 100 |
| Nesting depth | 10 |
| Sections directly under one parent | 500 |
| Content of one page | 1 MB |
| Sections on one page | 1,000 |
Content is measured in bytes of UTF-8, not characters: 16 KB is about 2,500 words of English, and fewer in scripts that take more bytes per character.
The page totals are the exception for edits: an edit that makes a section longer is accepted even if it takes the page over 1 MB, and new sections are then refused until there is room again.