Get started
Design blocks and sections
Plan and build the blocks editors place on pages, step by step, so every page has one main heading, headings in order, fields editors can fill in, and a website that renders exactly what SEO health checks.
Tutorial8 min read
Editors build pages from blocks: a hero, a text section, a grid of cards. You define each block once as a component, your website draws it, and SEO health checks the pages editors make with it. This guide takes one block from plan to page, and sets up the headings so that every page editors build has one main heading and headings in order, without them having to think about it.
Before you start
- You can open Schema › Components and Schema › Content types, which needs the right to manage the schema.
- Your website already renders pages from CMS Orbit. If not, start with Connect a website.
- Three words used below:
- A content type is a kind of page or entry, such as a page, an article or a trip.
- A component is a block editors place on a page, such as a hero or a text section.
- The main heading is the page's one H1, the heading that says what the page is about.
1Decide where each page's main heading comes from
Every page needs exactly one H1. Search engines read it as the page's subject, and screen reader users jump to it first. CMS Orbit can only check it if it knows which part of the page your website shows as the H1. Go through your content types and pick one of three patterns for each:
| The H1 comes from | Example | What to set |
|---|---|---|
| A block at the top of the page | A hero or page header on a landing page | Main heading of the page on the component |
| The entry's own field, printed by your template | A trip's title, an article's headline | Main heading of the page on the content type |
| A block that is the title only sometimes | A text block with a "use as page title" switch, for pages without a hero | Main heading of the page and Only when on the component |
Pick one pattern per content type. If a trip's template prints the title as the H1, don't also allow a hero on trips, or the page gets two.
2Plan the heading levels
Headings below the H1 should go down one level at a time, never skip one:
H1 Lofoten ridge walk H2 Who it suits H3 Fitness H2 Day by day- Sections are H2. A block that starts a new part of the page, such as "What's included" or "Questions", has an H2 heading.
- Items inside a section are H3. Cards in a grid, questions in a list, days in an itinerary.
- Rich text follows the block it sits in. Inside a section whose heading is an H2, editors use H3 in the text. In a text field directly under the H1, they use H2.
CMS Orbit checks the headings it can see: the main heading you declare, headings inside rich text, and a block's heading level when the block has a level field (see step 4). It can't see headings your website's templates add on their own. If a template prints a heading in front of editors' content, especially a hidden one, SEO health reports the content's headings as skipping a level, even though the page is fine. Either leave such headings out, or give the content the level that follows them.
3Create the component
- Open Schema › Components and select New component.
- Enter a Name editors will recognise, such as
Text section. The Key is made from it (textSection) and is what your website uses; it can't be changed later. - Choose where it may go:
- Allowed at the top of a page for blocks that make up the page.
- Can sit inside another component for blocks that live in a grid or a section.
- Select Create component, then open it to add its fields. A typical section has:
levelH2 and H3, default H2; see step 4| Field | Type | Notes |
|---|---|---|
| Heading | Text | Required, so a section never has an empty heading |
| Heading level | Select, key level | Choices H2 and H3, default H2; see step 4 |
| Text | Rich text | |
| Image | Asset | Editors add alt text in the media library |
Field types lists every type and its settings.
- If this block provides the page's main heading (step 1), choose its heading field under Main heading of the page. If it does so only when a switch is on, choose that yes/no field under Only when.
A component whose key contains hero is taken to provide the H1 when nothing else is set. Set Main heading of the page anyway, so the rule is written down and the right field is checked.
4Let editors choose a heading's level, where it can vary
Some blocks sit at different depths: a card grid can be a section of its own (H2) or part of a larger section (H3). Give such blocks a Select field with the key level and the choices H2, H3 and so on. The values are stored as h2, h3, which CMS Orbit reads as that block's heading level, so SEO health checks the order on every page. Set a default, usually H2, so editors only change it when they need to.
Blocks whose heading is always at the same level don't need the field. Then CMS Orbit doesn't count their heading, and only checks the headings it can see.
5Allow it where it belongs
- Open Schema › Content types and the content type, such as Page.
- Under Components at the top of the page, add the new component.
- For content types whose template prints the H1 (step 1), open the Search step and choose the field under Main heading of the page. Leave hero-style blocks out of their allowed components.
6Render it on your website
Draw the block with the heading tag that matches what you set in CMS Orbit. Type it with BlockProps and register it as in Render components.
import type { BlockProps } from '@bifrost-orbit-cms/sdk/react'import { RichText } from '@bifrost-orbit-cms/sdk/react'export function TextSection({ block }: BlockProps<'textSection'>) { const Heading = block.level ?? 'h2' return ( <section> <Heading className="section-heading">{block.heading}</Heading> <RichText value={block.text} /> </section> )}A block with Only when renders its heading as the H1 only while the switch is on:
export function Text({ block }: BlockProps<'text'>) { const Heading = block.asTitle ? 'h1' : 'h2' return <Heading>{block.heading}</Heading>}Choose the tag by meaning and the look by class. If an H2 should look smaller in one place, give it a class, not an H3.
7Check it before editors start
- Create a test page named
TEMP heading check, and place every block you made on it, with a heading in each and an H2 and H3 in the rich text. - Publish it to Staging and open it on your website. In the browser's developer tools, check there is exactly one
<h1>and the headings go down in order. - In CMS Orbit, open SEO › Health. Checks run on drafts as soon as they are saved, so the test page is already checked: under Issues by impact, none of the heading issues (No main heading, More than one main heading, Headings that skip a level, Empty headings) should list it.
- If your Staging site has a website address, the live check in SEO health compares what CMS Orbit expects with the page as your website serves it. See Improve SEO health.
- Delete the test page.
Checklist
- [ ] Every routable content type has one source of the H1: a component or the content type's own field.
- [ ] Blocks that provide the H1 have Main heading of the page set, and Only when if it depends on a switch.
- [ ] The heading field of a block that provides the H1 is required.
- [ ] Section blocks render H2, items inside them H3, and blocks that move between levels have a
levelfield. - [ ] Templates don't add headings in front of editors' content, or the content follows them.
- [ ] Your website renders the same tags CMS Orbit expects, and a test page passes SEO health.
Common problems
| SEO health says | Usually because | Fix |
|---|---|---|
| No main heading | No block or field is marked as the H1 | Step 1 and step 3, item 5 |
| No main heading, on pages without a hero | The H1 comes from a switch the schema doesn't know about | Set Only when |
| More than one main heading | A hero on a page whose template already prints the title | Remove the hero from that content type's allowed components |
| Headings that skip a level | A heading the template adds, or rich text one level too deep | Step 2 |
| Empty headings | An optional heading field left empty on a block that renders it | Make the heading required, or render nothing when it is empty |
Was this page helpful?