How we do development: Automatic Semantic Headings

Chris Gregori
multiverse-tech
Published in
4 min readMar 23, 2021

This is the first post in a series that I’m hoping to flesh out to talk about some of the interesting technical things we’re doing in the Multiverse Product & Tech team.

Photo by Kyle DeSantis on Unsplash

What are semantic headings?

Let’s start with the basics. HTML defines six levels of headings — a heading element implies all the font changes, paragraph breaks and any white space necessary to render the heading. They’re also numbered in order of importance starting with h1 all the way down to h6.

Essentially they are paragraph headings.

Headers play a massive role in making the hierarchical structure of a document explicit — heading information can be used by user agents to construct a table of contents for documents automatically and are extremely important for accessibility. Screen reader software often use headings to jump across and determine the content of the page, because of this skipping heading levels or nesting them incorrectly can create confusion and bad user experience.

We also don’t want to forget our friendly neighbourhood search engine spider-bots — having semantically correct headings helps search crawlers clearly identify what key terms are relevant for the page.

There are some rules you want to adhere to:

  • H1’s are also important to tell search engines (and people!) what the page is all about. Stick to a single h1 per section, article or aside elements — the most important titles of your ‘document’.
  • Always use the correct next sub-heading i.e. h2 after h1, h3 after h2 and so on.

Sounds easy — why write a blog post about this?

At Multiverse we recently undertook the project of creating a brand new website for our marketing and brand. The entire site has been rebuilt from scratch on a brand new tech stack, CMS, content methodology, design and tone of voice — more on this to come in subsequent series posts.

A large problem we had in the past with our old CMS was the inflexibility of page layout and content. As such, we decided to have the entire site powered by nested, reconfigurable and reusable components. The issue with this however is that semantic headings could get mismatched if you wanted to nest and compose components inside of one another where the components have headings. We don’t want a h2 as a child of a component that might have a h3 for example.

So what’s the solution?

Our new site is built in React on Next.js — to leverage the ease of integrations with our CMS (Sanity), the developer experience, and to take advantage of some existing experience in the team.

We wanted some way to automatically infer what a heading should be depending on what the last heading the parent element above it used.

Context to the rescue!

Some code has been removed for relevance

What we’re doing above is defining a context wrapper component to wrap all subsequent children of a page in. From there all we had to do was define a new <Section> anytime we wanted to go another heading level deep and by using <H> components our developers never had to worry about what heading level they should be using — it all gets taken care of at render time.

Example Use Case

By combining our <HeadingLevelProvider> in our common layout component we ensured that every page would start from a H1.

After that it was just a case of ensuring each component began with a <Section> (or incorporated a Section inside of our common component layout wrapper) and we wouldn’t need to ever worry about which Heading element to use. And now, regardless of how our marketing team decide to nest and use components the semantics of the page will never break.

This has been the first of a multi-part series. If there are any questions ask in the comments below or subscribe to Multiverse Tech to keep up with any future posts from myself or the team!

Join the team

Multiverse’s mission is to create a diverse group of future leaders. The products we are building are designed to connect apprenticeship candidates to employers and to set them up for success throughout their qualification. Our social mission is at the heart of our business, so if doing good is as important as building a commercial business to you, you will find Multiverse incredibly rewarding.

To view our latest open roles, visit our careers page. You could also check out Why you should join Multiverse by our awesome new VP of product Emma van Dijkum or find out how Alex Drummond has been using Rust in Elixir for HTML validation.

--

--

Chris Gregori
multiverse-tech

Senior Software Engineer @Multiverse — ex @Skyscanner & @NETAPORTER