sitekits.dev
press ⌘K to switch tools
NETWORK · HTTP

Heading & Link Extractor

Extract the heading outline and every link from a page by URL.

server
page-outline

🌐 sitekits fetches the URL server-side (private/internal addresses are blocked). The HTML is parsed as delivered — JavaScript is not executed, so client-rendered headings will not appear.

§01 ABOUT THIS TOOL

Overview

A page’s heading hierarchy is its outline, and it is read by more things than most people expect: search engines building a summary, screen readers offering a navigable heading list, and AI answer engines deciding what a page is about. When the outline is wrong, all of them degrade at once, and none of it is visible on screen — an h3 styled to look like a section title reads exactly like an h2.

This tool fetches a URL server-side, parses the HTML as delivered, and returns the complete heading tree, the h1 count, every skipped level, and every link split into internal and external with nofollow flagged.

How to use

  1. Paste a URL. The scheme may be omitted; https is assumed.
  2. Read the summary line: the h1 count, the number of headings, and level jumps.
  3. Switch between Outline and Links for the detail.

What the HTML-as-delivered rule means

No JavaScript is executed. This is a deliberate constraint, not a limitation to work around: it shows the page as anything that does not run scripts sees it.

If your headings come from a client-side framework, the outline here will be nearly empty — and that is the finding. Search engines do render JavaScript, but on their own schedule and with no guarantee, and many other consumers of your HTML never render at all: link previews, feed readers, text-mode browsers, and most AI crawlers. A server-rendered outline is the one every consumer sees.

<script> and <style> contents and HTML comments are removed before parsing, so a heading inside a commented-out block or a template string does not appear in the outline. Tags inside heading text are stripped and HTML entities are decoded, so <h2>Pricing &amp; plans</h2> reads as Pricing & plans.

Reading the level jumps

A jump is reported whenever a heading is more than one level deeper than the one before it: h1 to h3, or h2 to h5. Going back up is never a jump — h3 followed by h2 simply closes a subsection.

The reason to care is that heading level is the only signal of nesting in HTML. Screen-reader users move through a document by level, and a skipped level tells them a subsection exists that the content does not have. The usual cause is visual: an h4 was chosen because it was the right size, and the size was later changed in CSS anyway.

The fix is to pick levels by structure and set the size in CSS. The outline is then correct for every reader, and the appearance is unaffected.

Every link is resolved against the page’s final URL, so relative hrefs appear as the absolute URLs a crawler follows. Protocol-relative links (//host/path) inherit the page’s scheme. Malformed hrefs are dropped rather than reported as links.

rel="nofollow" is detected case-insensitively and within multi-value rel attributes, so rel="NoFollow noopener" is flagged. Note that nofollow has been a hint rather than a directive for crawling since 2019 — it no longer reliably prevents a link from being followed, which matters if you were relying on it to keep a URL out of an index. noindex on the target page is the only mechanism that does that.

Empty text is shown explicitly. A link with no text — commonly an icon-only anchor with no aria-label — is unreachable for screen-reader users and carries no signal about its destination.

Examples

  • Auditing a template, not a page — run one page per template. Heading defects almost always live in the template, so a handful of URLs covers a site.
  • Checking whether your content is server-rendered — if the outline is empty but the page is full of headings, nothing that skips JavaScript can read it.
  • Before a migration — capture the outline and link counts of key pages, then compare after. A dropped h1 or a section demoted by one level is otherwise very easy to ship unnoticed.
  • Finding accidental external links — a stray staging or CDN host in the external list usually means a hardcoded absolute URL that survived a deployment.
  • Preparing content for AI answer engines — a correct heading hierarchy is the cheapest structural signal available, and it is the one most often broken. The HTML validator covers markup errors, and OG preview covers how the page presents itself when shared.

What is not counted

Only <a href> elements are collected. <link>, <form action>, <iframe src> and JavaScript-driven navigation are excluded, because they are not links a crawler follows from the document.

Notes

Up to five redirects are followed, and every hop is revalidated against the same address rules, so a public URL cannot redirect into a private network. The outline describes the final response, and the chain is shown.

Reading stops at 1 MB and the report is capped at 300 headings and 500 links. When either limit is reached you are told, because a silently truncated outline looks like a complete one.

Requests to private, loopback, link-local and reserved addresses are refused before any connection is opened. The response body is parsed in memory to produce this report and is never stored — see the privacy policy.

FAQ
Why are headings missing that I can see in my browser?
The HTML is parsed as the server delivered it, with no JavaScript executed. Headings rendered by a client-side framework after load do not appear. That gap is itself useful information — a crawler that does not execute your JavaScript sees the same empty outline this tool does.
Does more than one h1 hurt SEO?
Not directly, and HTML5 sectioning permits it. What it costs you is clarity: with several h1 elements the page states no single subject at its top level, so anything summarising it — a search engine, a screen reader's heading list, an AI answer engine — has to guess which one is the page. The count is reported so you can decide, not scored.
What is a level jump and why does it matter?
A heading that skips a level, such as an h3 directly after an h1. Screen-reader users navigate by heading level, so a skipped level makes the outline claim a nesting depth the content does not have. It is a structural defect that is invisible on screen, which is why it is worth reporting.
Are fragment links and mailto: counted?
No. Empty href, in-page fragments (#top), javascript: and mailto: are excluded, because none of them is a link to a page. Everything else is resolved against the page URL, so relative links appear as the absolute URLs a crawler would follow.
How is internal versus external decided?
By comparing the resolved link's host with the final URL's host after redirects. A different subdomain counts as external, because search engines and browsers largely treat it that way too.
Is there a limit on how much is read?
The response is read up to 1 MB and reports up to 300 headings and 500 links. If the page exceeded 1 MB you are told so explicitly, rather than being shown a partial outline that looks complete.