A site audit says “missing H1,” and suddenly a perfectly ordinary page feels guilty of something. I have seen teams respond by dropping a giant heading into the first template they can find—then discover that product pages now have two titles, archive pages have the wrong one, and the original problem was only a hidden page-builder setting.

Let’s slow that moment down. The warning matters because a page should announce its subject clearly to readers, assistive technology, and search systems. It does not mean that adding the letters <h1> guarantees a ranking increase. The durable fix is to find which layer lost the page title, repair that layer, and inspect the HTML visitors actually receive.

Three titles are often mistaken for one another

  • Browser title: the <title> element appears in the browser tab and is an important source for search-result title links.

  • Page heading: the visible <h1> names the main content. It belongs in the document body and helps establish the heading hierarchy.

  • Social title: og:title supplies a title to platforms that understand Open Graph metadata.

  • These strings may be similar, but one does not replace another. Structured data does not repair a missing visible heading either.

Inspect the page your visitor gets—not the template you remember editing

Open the affected URL, launch browser developer tools, choose the Elements panel, and search for <h1. That rendered DOM includes changes made by JavaScript. “View Source” and command-line downloads may show only the server response, so they can tell a different story on client-rendered sites.

browser-console.jsjavascript
const headings = [...document.querySelectorAll('h1')];
 
console.table(
  headings.map((heading) => ({
    text: heading.textContent?.trim(),
    visible: Boolean(heading.offsetWidth || heading.offsetHeight),
    id: heading.id,
  })),
);

Count H1 elements in the rendered DOM and expose empty or visually hidden candidates.

What those rows are trying to tell you

  • querySelectorAll("h1") returns every native H1 in the current document after client-side rendering.

  • textContent?.trim() makes an empty heading obvious; an element without a useful name has not solved the problem.

  • offsetWidth and offsetHeight are a quick visibility clue, not a complete accessibility audit. A deliberately screen-reader-only heading can measure zero and still be exposed to assistive technology.

  • Run this in the page’s browser console. Do not paste scripts from strangers into a console on a site where you are signed in.

What healthy heading markup looks like

article.htmlhtml
<main>
  <article>
    <header>
      <h1>Configure SSH key authentication on Ubuntu</h1>
      <p>Use public-key authentication without locking yourself out.</p>
    </header>
 
    <h2>Before you change the SSH server</h2>
    <h2>Add the public key</h2>
    <h3>Check file permissions</h3>
    <h2>Test a second login</h2>
  </article>
</main>

Give the page one descriptive top-level heading and nest its sections by meaning.

The hierarchy should feel like a table of contents

  • The H1 describes this page—not the logo, site name, or navigation menu.

  • H2 elements introduce the article’s major sections; H3 belongs beneath the relevant H2.

  • A new H2 can follow an H3 because it closes that subsection. Jumping from H1 straight to H3 usually signals a structural gap.

  • Choose heading rank for document structure. Use CSS, not a lower or higher heading level, when you only want different typography.

Is more than one H1 a disaster?

No. Multiple H1 elements do not create an automatic search penalty. But “permitted” and “easy to understand” are not the same standard. Current MDN guidance recommends one H1 that describes the page, followed by headings nested without skipped levels. That convention gives template authors, screen-reader users, crawlers, and future maintainers one unambiguous main title.

If a component renders cards with their own H1 elements, make those card titles H2 or H3 according to their place in the surrounding page. If a modal or embedded application has a separate heading hierarchy, test its accessible structure rather than counting tags in isolation.

When WordPress loses the title

First confirm that the post or page has a title in the editor. Then determine whether the public page uses a block theme, a classic theme, or a page builder; the repair point differs.

  • Block theme: open Appearance → Editor, inspect the template used by the affected content type, and confirm that its Title block is present. The dynamic Title block renders the current post or page title.

  • Classic theme: inspect the relevant single.php, page.php, or template part in a child theme. Look for the title-rendering call and compare the affected template with a working one.

  • Page builder: check the document’s “hide title” option and the builder’s theme template. A title widget plus the theme title can create a duplicate, while disabling both creates the missing H1.

  • CSS issue: if an H1 exists in the DOM but readers cannot see it, inspect display, visibility, color contrast, clipping, positioning, and overlays before changing PHP.

  • Only some URLs fail: group failures by post type and template. A shared template defect is safer to fix once than to paste headings into every article body.

In Next.js, give one component ownership of the H1

app/docs/[slug]/page.tsxtsx
import type { Metadata } from 'next';
 
export async function generateMetadata({ params }): Promise<Metadata> {
  const post = await getPost((await params).slug);
  return { title: post.seoTitle, description: post.metaDescription };
}
 
export default async function DocumentationPage({ params }) {
  const post = await getPost((await params).slug);
 
  return (
    <main>
      <article aria-labelledby="article-title">
        <header>
          <h1 id="article-title">{post.title}</h1>
          <p>{post.excerpt}</p>
        </header>
        <RichText data={post.body} />
      </article>
    </main>
  );
}

Keep metadata and the visible page heading explicit, while the article body begins at H2.

The ownership rule prevents two opposite bugs

  • generateMetadata populates head metadata; it does not render a visible H1 in the document body.

  • The page component owns the article H1, while the rich-text body starts with H2. That contract prevents editors from duplicating the title.

  • aria-labelledby gives the article an accessible name tied to the visible title. It is helpful here, although the native heading remains the essential structure.

  • Layouts shared by many routes should not render a content-specific H1 unless they also own the title data for every route.

A diagnosis that does not turn into whack-a-mole

  1. Reproduce: open one flagged URL and one healthy URL from the same content type.

  2. Count: inspect H1 elements in the rendered DOM, including their text and visibility.

  3. Locate ownership: identify whether the CMS template, theme, page builder, application route, or body content should render the title.

  4. Repair upstream: change the shared component or template when the failure is systematic; use a page-level fix only for a genuine exception.

  5. Review hierarchy: ensure subsequent sections descend through H2 and H3 according to meaning.

  6. Sample the blast radius: test posts, pages, archives, search results, product pages, and error pages that reuse the changed layout.

Verify it like a reader, a crawler, and a maintainer

  • Reader: the page subject is visible near the beginning and accurately describes what follows.

  • Keyboard and screen-reader user: headings form a meaningful, navigable outline without unexplained level jumps.

  • Search system: server-rendered HTML contains a clear main title where possible, and the H1, title element, canonical URL, and page content describe the same intent.

  • Maintainer: the title comes from one known source, and reusable body content does not smuggle in another top-level heading.

  • Site owner: representative templates have been recrawled with the audit tool; a single green URL is not proof that the shared defect is gone.

If Google still displays a different result title after the fix, do not keep rewriting the H1 every morning. Title-link generation is automated, and recrawling takes time. Check for stale or boilerplate title elements, multiple equally prominent headings, inconsistent language, and conflicting link text. The H1’s job is to make the page honest and understandable; let it do that job well.

References used for this repair strategy