{
  "tools": [
    {
      "slug": "title-tag-checker",
      "title": "Title tag checker — length, keywords and the SERP headline",
      "h1": "Title tag checker",
      "description": "Paste a URL. See the live <title>, its character count, and whether it is missing, too short or likely truncated in search results.",
      "lead": "The title tag is the clickable headline in Google and the strongest on-page signal of what the page is about. A missing or generic title wastes the click you already earned a crawl for.",
      "category": "content",
      "icon": "bi-type",
      "checks": [
        "title"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "We read the first <title> in <head> and flag it if it is missing, shorter than 15 characters or longer than 60. Those bounds match what search results typically display before they add an ellipsis.",
            "The same run still collects every other check — this page just puts the title in front so you can fix the headline without wading through Open Graph and JSON-LD."
          ]
        },
        {
          "heading": "How to write one",
          "paragraphs": [
            "Lead with the term the page should rank for, then the brand if it fits. One title per URL; do not reuse a site-wide template that only changes the product name at the end.",
            "Common misses: an empty title, the raw filename, or a 90-character slogan that Google rewrites anyway."
          ]
        },
        {
          "heading": "Why the bounds are 15 and 60",
          "paragraphs": [
            "Google rewrites titles it considers too short, too long or off-topic, and it does so silently: you keep the tag, the result shows something else. Under 15 characters there is usually no room for the term and the qualifier; above 60 the desktop result cuts the end and mobile cuts earlier. The bounds are display limits measured in characters, not a scoring rule — a 62-character title is not a penalty, it is a headline you no longer control.",
            "The checker reads the first <title> inside <head>. A second <title> in the body, a title injected later by JavaScript, or a page that ships an empty tag and fills it client-side all count as what the crawler sees on the first fetch: the raw HTML."
          ]
        },
        {
          "heading": "Common mistakes",
          "paragraphs": [
            "The same title on every page of a section (a template that only changes the product name at the end, or not even that). The brand first and the topic last, so the part that gets truncated is the part that carried the term. A title that repeats the H1 word for word, wasting the one place where you can phrase the promise for the result page instead of for the reader who is already on it."
          ]
        }
      ],
      "example": {
        "title": "What the audit of https://example.com/ returned on 5 September 2026",
        "bad": "<title>Example Domain</title>\n<!-- 14 characters → title_short (warn) -->",
        "good": "<title>Example Domain — reserved names for documentation and tests</title>\n<!-- 60 characters: the term first, the reason to click after the dash -->",
        "note": "example.com scored 27/100 in that run. The title is not wrong, it is just too short to say what the page is for; the rewrite keeps the name and adds the purpose in the characters the result actually shows."
      },
      "faq": [
        {
          "q": "Is the title tag a ranking factor?",
          "a": "Yes, it is one of the strongest on-page signals of the page topic, and it is also the headline people click. Both effects are lost when the tag is generic or missing."
        },
        {
          "q": "Should the title and the H1 be identical?",
          "a": "They can be, but they serve different readers. The title speaks to someone scanning results; the H1 speaks to someone already on the page. Matching the topic is required; matching the wording is optional."
        },
        {
          "q": "What if my CMS adds the site name automatically?",
          "a": "Count it. If the platform appends “ | Brand” to every page, the 60-character budget includes those characters, and the checker measures the final tag, not the field you typed."
        }
      ],
      "_links": {
        "self": "https://pageaudit.online/api/tools/title-tag-checker",
        "html": "https://pageaudit.online/tools/title-tag-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "meta-description-checker",
      "title": "Meta description checker — the sales line under your title",
      "h1": "Meta description checker",
      "description": "See the meta description on a live URL, how long it is, and whether it is missing or likely cut off in the search snippet.",
      "lead": "A meta description is not a ranking factor. It is the sentence under your title that decides whether someone clicks. Leaving it blank hands that sentence to the search engine.",
      "category": "content",
      "icon": "bi-card-text",
      "checks": [
        "meta_description"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "We read <meta name=\"description\"> and flag missing, under 50 or over 160 characters. Those are display bounds, not scoring magic — a 40-character line is usually too thin to sell the click."
          ]
        },
        {
          "heading": "How to write one",
          "paragraphs": [
            "State what the page is and why it is worth opening. Include the main term once if it reads naturally. Do not stuff keywords or repeat the title verbatim.",
            "One description per URL. A site-wide boilerplate (“Welcome to our website”) is worse than none: it looks identical on every result."
          ]
        },
        {
          "heading": "Why 50 to 160 characters",
          "paragraphs": [
            "The description is the sentence under the headline in the result. Search engines show roughly 155–160 characters on desktop and fewer on mobile, and when the tag is missing or off-topic they build their own snippet from the page text. Under 50 characters the line rarely gives a reason to click; over 160 it is cut mid-sentence. These are display bounds — the checker flags them so you decide, it does not lower the score for a 165-character line that reads well.",
            "It reads the first <meta name=\"description\"> in the HTML that came back from the fetch. Descriptions set by JavaScript after load are not seen by the first crawl and are not seen here."
          ]
        },
        {
          "heading": "Common mistakes",
          "paragraphs": [
            "Leaving it empty on the pages that get the most impressions, because they were built from a template. Copying the first paragraph verbatim (the snippet then repeats what the reader will see anyway). Stuffing four variants of the term into one sentence, which reads like a listing and clicks like one."
          ]
        }
      ],
      "example": {
        "title": "What the audit of https://example.com/ returned on 5 September 2026",
        "bad": "<!-- no <meta name=\"description\"> in <head> → meta_description_missing (error) -->",
        "good": "<meta name=\"description\" content=\"Example Domain is reserved for documentation and tests: you can use example.com in manuals and code without asking permission.\" />\n<!-- 139 characters: what the page is, why it exists, and who it is for -->",
        "note": "The search engine will write its own snippet for example.com from the two sentences on the page. That is fine for a reserved domain; for a product page it means the sentence that sells the click is chosen by someone else."
      },
      "faq": [
        {
          "q": "Does the meta description affect ranking?",
          "a": "Not directly. It affects the click-through rate of the result, which is the number that turns impressions into visits. A page can rank and still lose the click to a neighbour with a clearer line."
        },
        {
          "q": "Can I use the same description on similar pages?",
          "a": "Each URL should have its own. Identical descriptions make near-duplicate results, and the engine tends to replace them with page text, so the work is lost anyway."
        },
        {
          "q": "Why does the result show a different text than my tag?",
          "a": "The engine chose page text it judged more relevant to that query. Usually the tag was generic, too short, or did not mention what the searcher typed."
        }
      ],
      "_links": {
        "self": "https://pageaudit.online/api/tools/meta-description-checker",
        "html": "https://pageaudit.online/tools/meta-description-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "canonical-tag-checker",
      "title": "Canonical tag checker — which URL should rank",
      "h1": "Canonical tag checker",
      "description": "See whether a page declares a rel=canonical, what it points at, and if that address differs from the URL you audited.",
      "lead": "When the same content is reachable from several URLs, the canonical tells search engines which address is the original so ranking signals are not split.",
      "category": "indexing",
      "icon": "bi-link-45deg",
      "checks": [
        "canonical"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "We look for <link rel=\"canonical\"> in <head>. Missing is a warning. If it is present and points somewhere other than the audited URL, we surface that — it is only correct when the page is a deliberate duplicate."
          ]
        },
        {
          "heading": "How to set one",
          "paragraphs": [
            "Use an absolute http(s) URL. Self-canonical on the preferred address. Do not point a unique page at the homepage, and do not let tracking parameters become a second indexable copy.",
            "A canonical to another host is a strong signal you do not want this URL indexed. Use that only when you mean it."
          ]
        }
      ],
      "example": null,
      "faq": [],
      "_links": {
        "self": "https://pageaudit.online/api/tools/canonical-tag-checker",
        "html": "https://pageaudit.online/tools/canonical-tag-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "h1-checker",
      "title": "H1 checker — one main heading, on topic",
      "h1": "H1 heading checker",
      "description": "List every H1 on a page. Catch a missing heading or a pile of H1s that leave the topic ambiguous.",
      "lead": "The H1 is the heading readers see first and the on-page statement of topic. Exactly one keeps that statement unambiguous.",
      "category": "content",
      "icon": "bi-type-h1",
      "checks": [
        "h1"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "We collect every <h1>. None is a fail. More than one is a warning: we show the full list so you can see which is the real title and which leaked from a template."
          ]
        },
        {
          "heading": "How to fix it",
          "paragraphs": [
            "One H1 that matches what the page is actually about — not the brand slogan from the header include. Subsections belong in H2/H3.",
            "A logo image with empty alt does not count as a heading. If the visual title is an image, give it an H1 in the document."
          ]
        },
        {
          "heading": "Why exactly one",
          "paragraphs": [
            "HTML allows several <h1> elements, and the outline algorithm that once justified one per section was never implemented by browsers or assistive technology. In practice a screen reader announces the first H1 as the page title, and search engines treat it as the strongest heading. Two H1s mean two claims about the topic; zero means the claim lives only in the <title>, which the reader on the page never sees.",
            "The checker collects every <h1> in the HTML that came back from the fetch, including ones inside headers, sidebars and footers — that is where the extra one usually hides, as a logo wrapped in a heading tag by a theme."
          ]
        },
        {
          "heading": "Common mistakes",
          "paragraphs": [
            "A theme that puts the site name in an <h1> on every page, so the article title becomes the second H1. A hero image with the visual headline baked into the picture and no heading in the document. Headings chosen by font size instead of hierarchy, so a page has H1, H3, H3, H5 and no H2 — the H1 check passes, but the structure below it does not help anyone."
          ]
        }
      ],
      "example": {
        "title": "What the audit of https://example.com/ returned on 5 September 2026",
        "bad": "<header><h1><a href=\"/\"><img src=\"logo.svg\" alt=\"\"></a></h1></header>\n<main><h1>Example Domain</h1></main>\n<!-- 2 H1 tags → h1_multiple (warn): the logo heading is the leak -->",
        "good": "<header><a href=\"/\"><img src=\"logo.svg\" alt=\"Example\"></a></header>\n<main><h1>Example Domain</h1></main>\n<!-- one H1, the one that states the topic; the logo is a link, not a heading -->",
        "note": "example.com itself passes this check: one <h1>Example Domain</h1> and nothing else. The bad snippet shows the pattern that fails on most themed sites — the same page with a logo wrapped in a heading."
      },
      "faq": [
        {
          "q": "Is more than one H1 a penalty?",
          "a": "No. The checker reports it as a warning because it makes the topic ambiguous for readers and machines; there is no fixed ranking penalty for a second H1, only the cost of a weaker statement."
        },
        {
          "q": "Does the H1 have to match the title tag?",
          "a": "It has to match the topic, not the wording. The H1 can be shorter and more direct because the reader already chose the page."
        },
        {
          "q": "My page is a single-page app and the H1 is rendered by JavaScript. Does it count?",
          "a": "Not on the first fetch. The checker reads the raw HTML; if the heading only exists after scripts run, a crawler without rendering sees no H1. Put it in the document."
        }
      ],
      "_links": {
        "self": "https://pageaudit.online/api/tools/h1-checker",
        "html": "https://pageaudit.online/tools/h1-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "viewport-checker",
      "title": "Viewport checker — mobile layout meta",
      "h1": "Mobile viewport checker",
      "description": "Confirm the page declares a mobile viewport. Without it, phones render the desktop layout zoomed out.",
      "lead": "The viewport meta is how you tell phones not to pretend they are a 980-pixel desktop. Missing it hurts usability and is a cheap mobile-ranking own-goal.",
      "category": "indexing",
      "icon": "bi-phone",
      "checks": [
        "viewport"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "We look for <meta name=\"viewport\">. Present is a pass; absent is a warning. We do not parse every token — the usual miss is the tag not being there at all."
          ]
        },
        {
          "heading": "The line that works",
          "paragraphs": [
            "Add <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> as early as you can in <head>. Avoid user-scalable=no unless you have a very specific app-like reason: it blocks pinch-zoom."
          ]
        }
      ],
      "example": null,
      "faq": [],
      "_links": {
        "self": "https://pageaudit.online/api/tools/viewport-checker",
        "html": "https://pageaudit.online/tools/viewport-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "charset-checker",
      "title": "Charset checker — stop mojibake before it ships",
      "h1": "Character encoding checker",
      "description": "See which character encoding the page declares. Without one, the browser guesses and accented text turns into garbage.",
      "lead": "A missing charset is how “São Paulo” becomes “SÃ£o Paulo”. The browser should not have to guess.",
      "category": "indexing",
      "icon": "bi-fonts",
      "checks": [
        "charset"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "We read <meta charset> (or the http-equiv equivalent). Missing is a warning. UTF-8 is what you want on a public page today."
          ]
        },
        {
          "heading": "Where it goes",
          "paragraphs": [
            "Put <meta charset=\"utf-8\"> as the first element inside <head>, before any title or script that might contain non-ASCII. A charset declared after the first 1024 bytes can be ignored."
          ]
        }
      ],
      "example": null,
      "faq": [],
      "_links": {
        "self": "https://pageaudit.online/api/tools/charset-checker",
        "html": "https://pageaudit.online/tools/charset-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "robots-meta-checker",
      "title": "Robots meta checker — is the page even allowed to rank?",
      "h1": "Noindex / robots meta checker",
      "description": "Read the robots meta on a live URL. A forgotten noindex removes the page from results no matter how good the rest of the audit is.",
      "lead": "A noindex directive is an instruction, not a suggestion. Staging leftovers that ship to production are the usual way a finished page stays invisible.",
      "category": "indexing",
      "icon": "bi-robot",
      "checks": [
        "indexable"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "We read <meta name=\"robots\"> (and report when it is absent — that defaults to indexable). A noindex in that tag is a fail: the page asked not to be indexed."
          ]
        },
        {
          "heading": "When noindex is correct",
          "paragraphs": [
            "Thank-you pages, filters, cart, internal search. Never on the URL you are trying to rank. After launch, grep the template for noindex before you look at title length."
          ]
        }
      ],
      "example": null,
      "faq": [],
      "_links": {
        "self": "https://pageaudit.online/api/tools/robots-meta-checker",
        "html": "https://pageaudit.online/tools/robots-meta-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "open-graph-checker",
      "title": "Open Graph checker — the card LinkedIn and Slack will show",
      "h1": "Open Graph checker",
      "description": "Inspect og:title, description, image, url, type and site_name on a live URL. Missing tags make a shared link look like a bare domain.",
      "lead": "Open Graph is how LinkedIn, Slack, Discord and WhatsApp build the preview card. Search tags do not fill this in. If og:image is missing, you get a text row.",
      "category": "social",
      "icon": "bi-share",
      "checks": [
        "og_title",
        "og_description",
        "og_image",
        "og_url",
        "og_type",
        "og_site_name"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "The six properties this product already extracts: title, description, image, url, type, site_name. Title, description and image are the ones that decide whether the card looks finished."
          ]
        },
        {
          "heading": "How to set them",
          "paragraphs": [
            "Absolute http(s) URLs only — relative og:image is dropped by most platforms. 1200×630 is the size that does not get cropped into a square.",
            "og:url should be the canonical address, not the campaign link the person pasted."
          ]
        },
        {
          "heading": "How the preview card is built",
          "paragraphs": [
            "When a link is pasted in WhatsApp, Slack, LinkedIn or Discord, the platform fetches the page once, reads the og:* tags in <head> and caches the result. og:title becomes the card headline, og:description the line under it, og:image the picture, og:url the address the card links to. None of these platforms fall back to the search tags; a page with a perfect title and meta description but no Open Graph gets a plain text row, or a card built from whatever image the scraper found first.",
            "The checker reads the six properties the audit already extracts — title, description, image, url, type, site_name — and flags the three that decide whether the card looks finished when they are missing. It reads the raw HTML, so tags injected by JavaScript are not seen, and neither are they by the scrapers."
          ]
        },
        {
          "heading": "Common mistakes",
          "paragraphs": [
            "A relative og:image (\"/og.png\"), dropped by most platforms. An image smaller than 200 pixels wide, which many scrapers ignore. A single site-wide og:image for every page, so every shared article shows the logo. og:url pointing at the campaign link that was shared instead of the canonical page, which splits the share counts. Changing the image and forgetting that the platforms cached the old card."
          ]
        }
      ],
      "example": {
        "title": "What the audit of https://example.com/ returned on 5 September 2026",
        "bad": "<!-- no og:title, og:description or og:image → three warnings; a share shows a bare link -->",
        "good": "<meta property=\"og:title\" content=\"Example Domain\" />\n<meta property=\"og:description\" content=\"Reserved names for documentation and tests, usable without permission.\" />\n<meta property=\"og:image\" content=\"https://example.com/og.png\" />\n<meta property=\"og:url\" content=\"https://example.com/\" />\n<meta property=\"og:type\" content=\"website\" />\n<!-- absolute image URL, 1200×630, the canonical address -->",
        "note": "example.com ships no Open Graph tags, so a shared link renders as text. The five lines above are the whole fix; the image is the only part that needs an asset."
      },
      "faq": [
        {
          "q": "Is Open Graph a ranking factor?",
          "a": "No. It decides how the page looks when someone shares it, which decides whether the share gets clicked. Search engines read the search tags; messaging apps read these."
        },
        {
          "q": "Which image size should I use?",
          "a": "1200×630 pixels is the size that is shown without cropping on the large-card layouts and scaled down on the small ones. Keep the subject in the centre; some platforms crop to a square."
        },
        {
          "q": "I changed the tags and the preview did not change. Why?",
          "a": "The platform cached the old card. Each one has a debugger or a re-scrape button (Facebook Sharing Debugger, LinkedIn Post Inspector); until you use it, the cached card stays."
        }
      ],
      "_links": {
        "self": "https://pageaudit.online/api/tools/open-graph-checker",
        "html": "https://pageaudit.online/tools/open-graph-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "twitter-card-checker",
      "title": "X / Twitter card checker — summary vs large image",
      "h1": "X (Twitter) card checker",
      "description": "See whether the page sets twitter:card and which format X will use. Without it, a link often renders as a plain text row.",
      "lead": "twitter:card chooses the card format on X. summary_large_image is the one that actually shows the picture. Missing the tag and X may not render a card at all.",
      "category": "social",
      "icon": "bi-twitter-x",
      "checks": [
        "twitter_card"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "We read <meta name=\"twitter:card\">. Missing is a warning. X falls back to Open Graph for title, description and image, so those still matter — but the card type itself is this tag."
          ]
        },
        {
          "heading": "What to put",
          "paragraphs": [
            "Use summary_large_image for articles and landing pages. Keep a dedicated twitter:image only if it should differ from og:image; otherwise OG is enough once the card type is set."
          ]
        }
      ],
      "example": null,
      "faq": [],
      "_links": {
        "self": "https://pageaudit.online/api/tools/twitter-card-checker",
        "html": "https://pageaudit.online/tools/twitter-card-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "json-ld-checker",
      "title": "JSON-LD checker — schema.org types on the page",
      "h1": "JSON-LD structured data checker",
      "description": "Count JSON-LD blocks on a URL and list the schema.org types. No structured data means a plain blue link in results.",
      "lead": "JSON-LD is how you feed rich results — breadcrumbs, FAQ, product, article. Without a block, you get the default blue link even if the HTML is perfect.",
      "category": "data",
      "icon": "bi-diagram-3",
      "checks": [
        "jsonld"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "We parse every <script type=\"application/ld+json\">, count the blocks and list the @type values. Zero blocks is informational, not a fail: plenty of pages rank without schema. It is still the gap that blocks rich results."
          ]
        },
        {
          "heading": "What to add",
          "paragraphs": [
            "Markup that matches the page: Article on an article, Product on a product, Organization on the homepage. Fake review stars and unrelated types get ignored or worse.",
            "This checker reports what is present. It does not validate against Google's rich-result rules — that is a different, stricter test."
          ]
        }
      ],
      "example": null,
      "faq": [],
      "_links": {
        "self": "https://pageaudit.online/api/tools/json-ld-checker",
        "html": "https://pageaudit.online/tools/json-ld-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "serp-preview",
      "title": "SERP preview — title and description as a search snippet",
      "h1": "SERP preview",
      "description": "Preview how a URL’s title, meta description and address sit in a search result snippet, using the tags already on the page.",
      "lead": "Google rewrites snippets when it wants to. You still control the default: a specific title and a description that sells the click. This preview is that default, not a ranking promise.",
      "category": "content",
      "icon": "bi-google",
      "checks": [
        "title",
        "meta_description"
      ],
      "serp": true,
      "sections": [
        {
          "heading": "What you see",
          "paragraphs": [
            "The host and path from the final URL, the <title>, and the meta description. If either tag is missing, the snippet shows the hole instead of inventing copy."
          ]
        },
        {
          "heading": "What this is not",
          "paragraphs": [
            "It is not a live Google screenshot and it does not pixel-match every device. Pixel-perfect SERP mocks go stale the week the UI changes. The tags are the part you can fix."
          ]
        }
      ],
      "example": null,
      "faq": [],
      "_links": {
        "self": "https://pageaudit.online/api/tools/serp-preview",
        "html": "https://pageaudit.online/tools/serp-preview",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "http-status-checker",
      "title": "HTTP status checker — does the URL even answer 200?",
      "h1": "HTTP status checker",
      "description": "See the HTTP status of a URL after redirects. Search engines only index addresses that answer 200.",
      "lead": "Everything else in this product assumes the URL returned a document. A 404, 410 or 5xx means there is nothing to rank, share or preview.",
      "category": "indexing",
      "icon": "bi-activity",
      "checks": [
        "http_status"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "The status of the final response after the fetch follows redirects. You see that code and the final URL. Soft-404s that return 200 with an error page are a different bug — they pass this check and fail the others."
          ]
        },
        {
          "heading": "What to do",
          "paragraphs": [
            "Pages you want indexed must return 200. Moved URLs should 301 to the canonical, not 302 in a loop. Gone URLs should 404 or 410, not a 200 empty template."
          ]
        },
        {
          "heading": "What each code means for indexing",
          "paragraphs": [
            "200 is the only answer that gets a page into the index. 301 and 308 move the address permanently and pass the signals to the target; 302 and 307 say the move is temporary, so the engine keeps the old URL and may not consolidate. 404 and 410 remove the page — 410 a little faster, because it states the page is gone on purpose. 5xx is read as a temporary outage: the engine retries for a while and then drops the page if it keeps failing, which is how a broken deploy can cost rankings weeks later.",
            "The checker follows redirects and reports the status of the final response together with the final URL, so a 301 chain that ends in 200 passes here and shows up in the redirect checker instead."
          ]
        },
        {
          "heading": "Common mistakes",
          "paragraphs": [
            "A soft 404: the server answers 200 with a “not found” template, so the engine indexes an error page. A maintenance page served with 200 instead of 503, which replaces every indexed page with the same text. A 302 left on a permanent move for years. An API that returns 200 with an error JSON body — the same bug, one layer down."
          ]
        }
      ],
      "example": {
        "title": "What the audit of https://example.com/ returned on 5 September 2026",
        "bad": "HTTP/1.1 200 OK\nContent-Type: text/html\n\n<h1>Page not found</h1>\n<!-- a soft 404: the status says \"index me\", the body says \"nothing here\" -->",
        "good": "GET https://example.com/ → 200 OK, final URL https://example.com/, 0 redirect hops\n<!-- what the checker recorded for example.com: a document, at its own address, first try -->",
        "note": "example.com answers 200 directly, with no hop. That is the boring, correct case. The bad snippet is the case the checker cannot catch on its own — a 200 wrapped around an error — which is why the title and H1 checks run on the same fetch."
      },
      "faq": [
        {
          "q": "The page opens in my browser. Why does the checker say 403?",
          "a": "Your browser sends cookies and a full user agent; the checker fetches like a crawler. A CDN or firewall that blocks unknown agents returns 403 to crawlers too, and those pages are not indexed."
        },
        {
          "q": "Is a 301 a problem?",
          "a": "Not by itself. A permanent redirect to the right page is the correct way to move content. It becomes a cost when it is a chain, when it points to a 404, or when internal links still use the old address."
        },
        {
          "q": "What should a removed page return?",
          "a": "404 or 410 with a real not-found page. Redirecting every dead URL to the home page is treated as a soft 404 and wastes the crawl."
        }
      ],
      "_links": {
        "self": "https://pageaudit.online/api/tools/http-status-checker",
        "html": "https://pageaudit.online/tools/http-status-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "image-alt-checker",
      "title": "Image alt checker — missing attribute vs decorative empty alt",
      "h1": "Image alt text checker",
      "description": "Count <img> tags on a live URL. Missing alt is a miss; alt=\"\" is decorative and counted separately so a spacer is not treated as a forgotten caption.",
      "lead": "Alt is what image search and a screen reader get. The usual bug is the attribute not being there at all. An empty alt on a decorative mark is correct — this checker does not lump the two together.",
      "category": "content",
      "icon": "bi-image",
      "checks": [
        "images"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "Every <img> in the HTML we already downloaded. We split the set into: has text, alt=\"\" (decorative), and no alt attribute. Only the last group raises a warning.",
            "We do not fetch the image bytes and we do not invent alt from the filename. A data: URI still counts as an image if it is in an <img> tag."
          ]
        },
        {
          "heading": "How to write alt",
          "paragraphs": [
            "Describe the picture in a short clause. If the image is a link, the alt is the link purpose, not “logo”. If it is purely decorative, alt=\"\" — do not omit the attribute.",
            "Background images in CSS are not in this count. If the meaning lives only in a background, put it in the document as text or a real <img>."
          ]
        },
        {
          "heading": "What alt is for, and what it is not",
          "paragraphs": [
            "The alt attribute is the text that stands in for the image: a screen reader reads it aloud, a browser shows it when the file fails, and image search indexes it. It is not a caption, not a place for keywords, and not required to describe every pixel. A product photo needs the product name and the distinguishing detail; a chart needs its conclusion; a logo that links to the home page needs the destination, because the alt becomes the link text.",
            "The checker splits every <img> into three groups: alt with text, alt=\"\" and no alt attribute at all. Only the last group is a warning. An empty alt is a deliberate statement that the image is decorative, and assistive technology skips it — which is what you want for a divider or a background pattern."
          ]
        },
        {
          "heading": "Common mistakes",
          "paragraphs": [
            "Omitting the attribute so the screen reader falls back to the file name (“IMG_4032.jpg”). Writing “image of” or “picture of” — the reader already knows it is an image. Putting the whole product description in the alt of a thumbnail. Marking a meaningful chart as decorative because the layout had no room for text. Using alt on a CSS background, where it does not exist — the meaning has to move into the document."
          ]
        }
      ],
      "example": {
        "title": "What the audit of https://example.com/ returned on 5 September 2026",
        "bad": "<img src=\"/img/report-q3.png\">\n<!-- no alt attribute → img_alt_missing (warn); a reader hears \"report-q3.png\" -->",
        "good": "<img src=\"/img/report-q3.png\" alt=\"Q3 revenue up 12% over Q2, driven by the API plan\">\n<img src=\"/img/divider.svg\" alt=\"\">\n<!-- the chart says its conclusion; the divider is declared decorative -->",
        "note": "example.com has no images at all (total 0), so the check passes trivially. The snippets show the two decisions the checker is really about: say what matters, or say explicitly that nothing does."
      },
      "faq": [
        {
          "q": "Is missing alt a ranking problem?",
          "a": "It is an accessibility failure first, and image search cannot index what it cannot read. On a page where images carry the content — products, charts, screenshots — it also removes the text that would have matched the query."
        },
        {
          "q": "When is alt=\"\" correct?",
          "a": "When the image adds nothing a reader needs: spacers, decorative shapes, a photo that repeats the adjacent text. The attribute must be present and empty; omitting it is the failure."
        },
        {
          "q": "Does the checker look at the image files?",
          "a": "No. It reads the <img> tags in the HTML. Size, format and lazy loading are performance questions; this tool answers whether each image has a text equivalent."
        }
      ],
      "_links": {
        "self": "https://pageaudit.online/api/tools/image-alt-checker",
        "html": "https://pageaudit.online/tools/image-alt-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "link-checker",
      "title": "Link checker — same host, other host, nofollow",
      "h1": "Internal and external link checker",
      "description": "Count same-origin and off-site <a href> on a live page, plus nofollow. Hash-only, mailto, tel and javascript: hrefs are skipped so they do not inflate the graph.",
      "lead": "Internal links are how a crawler finds the next page and how ranking spreads. A document with none is a dead end. External links are fine; this is a census, not a penalty.",
      "category": "content",
      "icon": "bi-box-arrow-up-right",
      "checks": [
        "links"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "Each <a> with an http(s) href, resolved against the final URL. Same origin counts as internal. rel containing nofollow is tallied on top, not instead.",
            "We do not crawl the destinations. A 404 behind an internal link is a different job. Relative paths such as /about are internal once resolved."
          ]
        },
        {
          "heading": "What to change",
          "paragraphs": [
            "Give the page at least a few descriptive internal links — not “click here”, and not a footer-only graph. Nofollow belongs on untrusted user content, not on your own articles.",
            "This is not a backlink index and not a broken-link crawler. It answers “what does this HTML point at?” after one fetch."
          ]
        },
        {
          "heading": "Why internal links are counted at all",
          "paragraphs": [
            "A crawler discovers pages by following links, and a page with no internal links is reachable only through the sitemap or from outside. Internal links also carry the anchor text that tells the engine what the destination is about; a site whose only internal links are the navigation has one description for every page — the menu label. This tool counts what the HTML points at after one fetch so you can see whether the page is a node in the site or a leaf.",
            "Each <a> with an http(s) href is resolved against the final URL. Same origin is internal, anything else external, and rel=\"nofollow\" is tallied separately because a nofollow link exists on the page but passes no endorsement."
          ]
        },
        {
          "heading": "Common mistakes",
          "paragraphs": [
            "Article pages with zero links in the body, so every related page depends on the menu. Anchor text that says “here”, “read more” or the bare URL. Nofollow on your own product pages because a plugin applied it to every external-looking link, including your subdomain. Links to the HTTP version of your own site, counted as external because the origin differs."
          ]
        }
      ],
      "example": {
        "title": "What the audit of https://example.com/ returned on 5 September 2026",
        "bad": "<p>This domain is for use in illustrative examples in documents.</p>\n<p><a href=\"https://www.iana.org/domains/example\">More information...</a></p>\n<!-- links: total 1, internal 0, external 1, nofollow 0 -->",
        "good": "<p>This domain is for use in illustrative examples in <a href=\"/docs/\">documents</a>.</p>\n<p><a href=\"/about/\">Why example.com is reserved</a> · <a href=\"https://www.iana.org/domains/example\">IANA registration</a></p>\n<!-- two internal links with descriptive anchors, the external one kept -->",
        "note": "example.com has exactly one link and it leaves the site. For a one-page domain that is the whole truth; for a product page the same census would mean no path to the pricing, the docs or the next article."
      },
      "faq": [
        {
          "q": "How many internal links should a page have?",
          "a": "Enough that every page a reader would want next is one click away, with anchor text that names it. There is no magic number; three descriptive links beat forty menu items."
        },
        {
          "q": "Does this tool find broken links?",
          "a": "No. It counts and classifies the links in the HTML; it does not fetch the destinations. Use the HTTP status checker on the URLs you care about."
        },
        {
          "q": "Are links inside the header and footer counted?",
          "a": "Yes, everything in the fetched HTML counts. That is why a page with a large menu can show many internal links and still have none in the content."
        }
      ],
      "_links": {
        "self": "https://pageaudit.online/api/tools/link-checker",
        "html": "https://pageaudit.online/tools/link-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "word-count-checker",
      "title": "Word count checker — readable text after scripts are stripped",
      "h1": "Visible word count checker",
      "description": "Count words a person can read on the live HTML. <script> and <style> are removed first so a 40 KB bundle does not look like an article.",
      "lead": "Word count is not a ranking target. It is a sanity check that the document has substance. A hero of images and a 12-word caption is a thin page, even if the file is large.",
      "category": "content",
      "icon": "bi-text-paragraph",
      "checks": [
        "word_count"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "Visible text after tags, scripts, styles and noscript blocks are stripped. Tokens need a letter or digit to count — a row of punctuation is not a word.",
            "We do not run the page’s JavaScript. Copy injected only after hydration is invisible here. If the article lives in a client render, this number will look unfairly small — that is the signal."
          ]
        },
        {
          "heading": "What it is not",
          "paragraphs": [
            "There is no “minimum 300 words” pass mark. Thin is context: a contact page can be short; a buying guide should not be. Use the number next to the rest of the audit, not as a quota."
          ]
        }
      ],
      "example": null,
      "faq": [],
      "_links": {
        "self": "https://pageaudit.online/api/tools/word-count-checker",
        "html": "https://pageaudit.online/tools/word-count-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "hreflang-checker",
      "title": "hreflang checker — language alternates, not the lang attribute",
      "h1": "hreflang alternate checker",
      "description": "List <link rel=\"alternate\" hreflang> on a live URL. Absence is normal on a single-language site. On a translated site it is how you stop the locales from competing.",
      "lead": "hreflang tells the index which language or region variant to show. It is not <html lang>, and it is not a canonical. Mixing those three is how a /en and a /pt page steal each other’s ranking.",
      "category": "indexing",
      "icon": "bi-translate",
      "checks": [
        "hreflang"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "Every <link> whose rel includes alternate and that also has hreflang. Href is resolved against the audited URL. Duplicates of the same lang+href are collapsed. We cap the list so a huge storefront does not blow the report.",
            "We do not fetch the other locales, so we cannot prove the return tags. This page reports what this document declares."
          ]
        },
        {
          "heading": "How to set it",
          "paragraphs": [
            "One link per language or region (en, pt-BR, x-default). Absolute http(s) URLs. Each locale should point at the others, including itself. Do not invent a hreflang cluster for a site that only exists in one language."
          ]
        },
        {
          "heading": "What a correct cluster looks like",
          "paragraphs": [
            "Every language version lists every other version and itself, with the same set of links on each page. That symmetry is what the engine uses to confirm that /en and /pt-br are the same content for different readers rather than two competing pages. One x-default points at the version to show when no language matches — usually the language picker or the original.",
            "Codes follow ISO 639-1 for the language (en, pt, es) with an optional ISO 3166-1 region (pt-BR, en-GB). A region without a language (BR) is invalid and ignored. The href must be absolute and must return 200 with the same alternates in its own head."
          ]
        },
        {
          "heading": "Common mistakes",
          "paragraphs": [
            "Declaring alternates on the English page only, so the Portuguese page never confirms the relationship (the engine then drops the cluster). Pointing hreflang at a redirect or a page with a different canonical. Inventing regional variants that serve identical content, which creates duplicates instead of alternates. Using the country code alone because the site is “for Brazil”."
          ]
        }
      ],
      "example": {
        "title": "A two-language page that passes, and the same page as most sites ship it",
        "bad": "<link rel=\"alternate\" hreflang=\"BR\" href=\"/pt\" />\n<link rel=\"alternate\" hreflang=\"en\" href=\"/en\" />\n<!-- BR is not a language; relative hrefs; no x-default; the /en page lists nothing back -->",
        "good": "<link rel=\"alternate\" hreflang=\"pt-BR\" href=\"https://example.com/pt\" />\n<link rel=\"alternate\" hreflang=\"en\" href=\"https://example.com/en\" />\n<link rel=\"alternate\" hreflang=\"x-default\" href=\"https://example.com/\" />\n<!-- the same three links, in that form, on /pt, /en and / -->",
        "note": "The audit of example.com on 5 September 2026 found no hreflang at all, which is correct: the page exists in one language. A cluster is only worth declaring when the alternates really exist."
      },
      "faq": [
        {
          "q": "Do I need hreflang if my site has only one language?",
          "a": "No. hreflang describes alternates; with a single version there is nothing to describe, and a self-referencing tag alone adds nothing."
        },
        {
          "q": "Does this checker verify the return links on the other pages?",
          "a": "No. It reports what the audited document declares. To confirm the return tags, run the checker on each alternate URL — the sets should be identical."
        },
        {
          "q": "hreflang or canonical: which one wins?",
          "a": "They do different jobs. Canonical says “this is the preferred URL for this content”; hreflang says “this content also exists for that language”. Each language version should be canonical to itself and list the others as alternates."
        }
      ],
      "_links": {
        "self": "https://pageaudit.online/api/tools/hreflang-checker",
        "html": "https://pageaudit.online/tools/hreflang-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "deprecated-markup-checker",
      "title": "Deprecated markup checker — font, center, marquee, inline style",
      "h1": "Deprecated HTML checker",
      "description": "Scan a live page for retired presentational tags (<font>, <center>, <marquee> and the rest) and count inline style= plus <style> blocks.",
      "lead": "Those tags were replaced years ago. Some browsers still paint them; crawlers and accessibility trees treat them as noise. Inline CSS is counted so a template that styles every <p> by hand shows up.",
      "category": "content",
      "icon": "bi-code-slash",
      "checks": [
        "legacy"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "A fixed list of retired elements: font, center, marquee, blink, big, strike, tt, frame, frameset, applet, basefont, dir, isindex, nobr. Any hit is informational, not a fail — old CMSs still emit them.",
            "style= on any tag and the number of <style> blocks are reported next to that. We do not parse the CSS or judge whether a rule is “too much”."
          ]
        },
        {
          "heading": "What to do",
          "paragraphs": [
            "Move presentation to a stylesheet. Replace <font> and <center> with CSS. Framesets and applet have no modern stand-in — those pages need a rebuild, not a class name."
          ]
        }
      ],
      "example": null,
      "faq": [],
      "_links": {
        "self": "https://pageaudit.online/api/tools/deprecated-markup-checker",
        "html": "https://pageaudit.online/tools/deprecated-markup-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "robots-txt-checker",
      "title": "robots.txt checker — the host file, not the robots meta tag",
      "h1": "robots.txt file checker",
      "description": "Fetch https://your-host/robots.txt, list Sitemap: lines and say whether User-agent: * has Disallow: /. This is a different check from the robots meta on the page.",
      "lead": "Crawlers look at /robots.txt before they look at the HTML. A forgotten Disallow: / for * is how a launch stays invisible. A 404 here is common and not fatal — but then you also have nowhere to declare the sitemap.",
      "category": "crawl",
      "icon": "bi-file-earmark-text",
      "checks": [
        "robots_txt"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "A separate fetch of {origin}/robots.txt after the page audit. HTML served in that slot (a SPA fallback) is treated as missing. We record status, Sitemap: URLs, user-agents seen, and whether * disallows /.",
            "We do not evaluate every path against every bot. If you need “is /blog allowed for Googlebot?”, that is a full robots parser — this tool answers whether the file exists and what it declares."
          ]
        },
        {
          "heading": "Do not confuse it with robots meta",
          "paragraphs": [
            "The robots meta (and X-Robots-Tag) lives on the page and can noindex a single URL. robots.txt is the host-wide door. Staging leftovers usually leak through the file, not the meta. Use the other tool for noindex."
          ]
        },
        {
          "heading": "What the file can and cannot do",
          "paragraphs": [
            "robots.txt controls crawling, not indexing. A URL blocked by Disallow can still appear in results if other pages link to it, shown without a snippet; to keep a page out of the index it must be crawlable and carry a noindex meta or header. The file lives at the root of the host, applies to that host only (www and apex are two files), and is read before the crawler fetches anything else. It is also where the Sitemap: line tells crawlers where the sitemap lives, which is why a 404 here costs more than it seems.",
            "The checker fetches {origin}/robots.txt after the page audit, records the status, the user-agents and Sitemap lines it finds, and whether the * group disallows /. HTML in that slot — a single-page app answering every path with the shell — is reported as missing, because that is what a crawler concludes too."
          ]
        },
        {
          "heading": "Common mistakes",
          "paragraphs": [
            "A staging file (Disallow: /) shipped to production with the rest of the deploy. Blocking the CSS and JS folders, which stops the engine from rendering the page as a visitor sees it. Using Disallow to hide a page that is already indexed — it stays, now without a description. Forgetting the Sitemap line, or pointing it at a sitemap on a different host, which is ignored."
          ]
        }
      ],
      "example": {
        "title": "What the audit of https://example.com/ returned on 5 September 2026",
        "bad": "GET https://example.com/robots.txt → 404\n<!-- robots_txt_missing (info): allowed by default, but no Sitemap line and no place to shape the crawl -->",
        "good": "User-agent: *\nAllow: /\nDisallow: /api/\n\nSitemap: https://example.com/sitemap.xml\n<!-- explicit, small, and it names the sitemap -->",
        "note": "A missing file is not an error: everything is allowed. The checker reports it as information because a site with a sitemap and no robots.txt has nowhere to declare it, and because the staging leftover that blocks everything looks exactly like the correct file until someone reads it."
      },
      "faq": [
        {
          "q": "Will a 404 robots.txt hurt my ranking?",
          "a": "No. Crawlers treat a missing file as “allow everything”. The cost is indirect: no Sitemap line, and no way to keep crawlers out of search results pages, filters and other URL noise."
        },
        {
          "q": "Does Disallow remove a page from Google?",
          "a": "No. It stops the crawl, and a page that is linked can still be indexed from the links alone. Use a noindex meta tag on a crawlable page to remove it."
        },
        {
          "q": "Does this tool check whether a specific path is allowed for a specific bot?",
          "a": "No. It reports whether the file exists, which agents it mentions, the sitemap lines and whether * disallows /. Path-by-path evaluation needs a full parser and the bot's exact name."
        }
      ],
      "_links": {
        "self": "https://pageaudit.online/api/tools/robots-txt-checker",
        "html": "https://pageaudit.online/tools/robots-txt-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "xml-sitemap-checker",
      "title": "XML sitemap checker — urlset or index, counted loc entries",
      "h1": "XML sitemap checker",
      "description": "Fetch the sitemap robots.txt declared, or /sitemap.xml if it declared none. Count <loc>, tell urlset from sitemapindex, and reject HTML served in that place.",
      "lead": "A sitemap is the list of URLs you want crawled. Without one, a new page waits to be discovered. An HTML homepage at /sitemap.xml is worse than nothing: it looks like a file and is not.",
      "category": "crawl",
      "icon": "bi-diagram-2",
      "checks": [
        "sitemap"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "We fetch /sitemap.xml in parallel with robots.txt. If robots.txt names a different http(s) sitemap, that URL wins — unless it fails the public-URL guard, in which case we do not follow it.",
            "urlset vs sitemapindex, the loc count (capped scan), and a short sample. We do not recurse an index and we do not download gzipped sitemaps in this pass."
          ]
        },
        {
          "heading": "What belongs in it",
          "paragraphs": [
            "Canonical, indexable URLs that respond 200. Not noindex, not redirects, not 404s. If the file needed shards, it became a catalog — keep the index small and honest."
          ]
        }
      ],
      "example": null,
      "faq": [],
      "_links": {
        "self": "https://pageaudit.online/api/tools/xml-sitemap-checker",
        "html": "https://pageaudit.online/tools/xml-sitemap-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    },
    {
      "slug": "redirect-checker",
      "title": "Redirect checker — every hop, re-checked, not a silent follow",
      "h1": "Redirect chain checker",
      "description": "Follow 3xx hops one at a time (redirect: manual) and list the chain. Each Location is run through the same public-URL guard as the first address. Three or more hops is a warning.",
      "lead": "A silent follow only shows the last URL. This checker shows the path: 301 → 302 → 200. Long chains waste crawl budget and drop referrers. A hop to a private or metadata address is refused and is not fetched.",
      "category": "crawl",
      "icon": "bi-arrow-left-right",
      "checks": [
        "redirects"
      ],
      "serp": false,
      "sections": [
        {
          "heading": "What we measure",
          "paragraphs": [
            "Up to ten hops. Relative Location is resolved against the current hop. javascript: and non-http(s) targets abort the chain. A loop is an error, not a long success.",
            "The report lists status per hop. We never store a blocked Location (nothing like 169.254 ends up in the JSON). The final document, if we got one, is the same HTML the rest of the audit uses."
          ]
        },
        {
          "heading": "How to flatten it",
          "paragraphs": [
            "One 301 from the old address to the canonical. Do not stack http→https, www→apex and trailing-slash as three separate hops if you can collapse them.",
            "This is not the HTTP status tool. That one tells you the final code. This one tells you how expensive it was to get there."
          ]
        },
        {
          "heading": "Why three hops is where the warning starts",
          "paragraphs": [
            "Each hop is a full request: a DNS lookup if the host changes, a TLS handshake, a round trip, then the next Location. Crawlers follow a limited number of hops per URL and give up on long chains; browsers show a blank tab until the last one answers. The checker follows up to ten hops and flags a chain at three or more, because two is what a normal migration produces (http to https, then the moved page) and three usually means nobody looked.",
            "It also refuses to follow a Location that points at a private or metadata address and records that as an error rather than fetching it. A loop — a hop that returns to an address already visited — is reported as an error, not as a long chain."
          ]
        },
        {
          "heading": "Common mistakes",
          "paragraphs": [
            "Stacking rules that each fix one thing: http → https, then www → apex, then trailing slash, then the moved page, four hops for a URL that could jump straight to the destination. Redirecting with 302 during a migration and forgetting to change it to 301. Leaving internal links pointing at the old address, so every visitor and every crawl pays the chain again."
          ]
        }
      ],
      "example": {
        "title": "A chain the checker flags, and the same move done in one hop",
        "bad": "http://example.com/old-page   → 301 https://example.com/old-page\nhttps://example.com/old-page  → 301 https://www.example.com/old-page\nhttps://www.example.com/old-page → 302 https://www.example.com/new-page\n<!-- 3 hops → redirect_chain_long (warn); the last one is still temporary -->",
        "good": "http://example.com/old-page → 301 https://www.example.com/new-page\n<!-- one permanent hop to the final address; https and www resolved in the same rule -->",
        "note": "The audit of example.com on 5 September 2026 recorded 0 hops: the URL answers 200 at its own address. The snippets above use the same host to show the shape of a chain the way the checker prints it, hop by hop."
      },
      "faq": [
        {
          "q": "Do redirects lose ranking signals?",
          "a": "A single permanent redirect passes them. The loss comes from chains that crawlers stop following, from temporary redirects that never consolidate, and from links that keep pointing at the old address."
        },
        {
          "q": "301 or 308?",
          "a": "Both are permanent. 308 also guarantees the method and body are kept, which matters for POST; for page moves 301 is the common choice and search engines treat them the same."
        },
        {
          "q": "Why is my redirect to the home page a problem?",
          "a": "Because the old page had a topic and the home page has another. The engine treats a mass redirect to the home as a soft 404 and the old rankings are not transferred."
        }
      ],
      "_links": {
        "self": "https://pageaudit.online/api/tools/redirect-checker",
        "html": "https://pageaudit.online/tools/redirect-checker",
        "audit": "https://pageaudit.online/api/audit",
        "workspace": "https://pageaudit.online/",
        "hub": "https://pageaudit.online/api/tools",
        "api_index": "https://pageaudit.online/api/"
      }
    }
  ],
  "_links": {
    "self": "https://pageaudit.online/api/tools",
    "html": "https://pageaudit.online/tools",
    "api_index": "https://pageaudit.online/api/"
  }
}